字符串,是我们平时接触最多的,正如我此刻正在通过键盘敲字一样,就是在文本输入框中输入字符串。包括我们平时用QQ等交流工具,以及在百度谷歌中输入关键字,等操作的都是字符串。那么,在JAVA中,是如何定义字符串和操作它呢?
根据JAVA中万物皆对象的思想,我们也将字符串看作是一个特殊的对象。这个对象一旦初始化就不能改变。
看到这里,也许很多小伙伴也和我第一次一样,都惊呆了。。。。。 因为我们平时在使用的时候,都会这样:
String a="abc";这不就改变了么,怎么会叫一旦初始化就不能改变呢?听我慢慢道来
a="def";
在java中将字符串看作一个对象,那么其类型String就是一个类,String类。 那么,"abc"就是一个对象,根据我们前面学习的,引用型变量a指向"abc"在堆内存的地址。 当a="def"时,是将对象"def"在内存中的地址值赋给引用型变量a,即a不再指向"abc"。
String s1="abc";上面两句代码中,s1和s2有什么区别吗? s1和s2的区别: s1在内存中有一个对象,即"abc" s2在内存中有两个对象,即new String() 和"abc"
String s2=new String("abc");
String类代表字符串,java程序中的所有字符串字面值(如"abc")都作为此类的实例实现。
再看一下面这段代码:
<span style="white-space:pre"></span>String s1="abc";
String s2=new String("abc");
System.out.println(s1==s2);//结果为false 比较的是地址值,两者指向不同的对象,所以为false
System.out.println(s1.equals(s2));//结果为true String类复写了Object类中equals方法,该方法用于判断字符串是否相同
从上面可以看出 1、s1和s2分别指向两个不同的对象。 2、String类复写了Object类中的equals方法,使其用于判断字符串的面值是否相同
再看下一段代码:
String s1="abc";结果为true 。疑惑:按刚才上面的理解,s1和s3应该是分别指向不同的对象,所以结果应该是false 才对。这里为何是true呢? 原因,"abc"为一个常量,因为它初始化后不可改变,所以它存放位置不是在堆内存中,而是在常量池中。为了节省空间,当在定义s3时,在常量池中已经存在了,所以s3直接指向“abc”,所以s1和s2指向的是同一个对象。
String s3="abc";
System.out.println(s1==s3);
String 类是用于描述字符串事物,那么它就提供了多个方法对字符串进行操作
常见的方法
1、获取
1、1 字符串中的包含的字符数,也就是字符串的长度。
int length();获取长度
1、2 根据位置获取指定位置上某个字符
char charAt(int index)
1、3 根据字符获取该字符在字符串中的位置。
int indexOf(int ch):返回的是ch在字符串中第一次出现的位置
int indexOf(int ch,int fromIndex):从fromIndex指定位置开始获取ch在字符串中第一次出现的位置
1、4 int indexOf(String ch):返回的是字符串ch在字符串中第一次出现的位置
int indexOf(String ch,int fromIndex):从fromIndex指定位置开始获取字符串ch在字符串中第一次出现的位置
int lastIndexOf(int ch)|int lastIndexOf(int ch,int fromIndex)
int lastIndexOf(String ch) |int lastIndexOf(String ch,int fromIndex)
方法示例:
class StringMethodTest
{
public static void method_get()
{
String str="adfhghj";
sop("原字符串:"+str);
//获取长度
sop("方法:length():"+str.length());
//根据索引获取字符
sop("方法:charAt(4):"+str.charAt(4));//当访问到字符串中不存在的角标时会发生StringIndexOutOfBoundsException
//根据字符获取索引
sop("方法:indexOf('g',2):"+str.indexOf('g',2));//若没有找到,则返回-1
}
public static void main(String[] args)
{
method_get();
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
结果:
2、判断
2、1 字符串中是否包含某一个子串
boolean contains(String str)
特殊之处:indexOf(str):可以索引str第一次出现的位置,如果返回-1。表示该str不在字符串中存在。
所以,也可以用于对指定判断是否包含。
eg:if(str.indexOf("aa")!=-1) 则包含。即可以判断,又可获取所在位置
2、2 字符串中是否有内容
boolean isEmpty() 原理就是判断长度length()是否为0
2、3 字符串是否是以指定内容开头
boolean startsWith(String str)
2、4 字符串是否是以指定内容结尾
boolean endsWith(String str)
2、5 判断字符串内容是否相同。复写了Object中的equals方法
boolean equals(str);
2、6 判断内容是否相同,并忽略大小写。
boolean equalsIgnoreCase();
代码示例:
public static void method_Is()
{
String str="ArrayDemo.java";
sop(str.startsWith("Array"));
sop(str.endsWith(".java"));
sop(str.contains("Demo"));
}
结果:
3、转换
3、1 将字符数组转成字符串
构造函数:String(char[] ch) 将字符数组转成字符串
String(char[],int offset,int cout);将字符数组中的一部分转成字符串
静态方法:static String copyValueOf()
static String valueOf(char[])
3、2 将字符串转成字符数组
char[] toCharArray();
3、2 将字节数组转成字符串
String(byte[])
3、4 将字符串转成字节数组
byte[] getBytes();
3、5 将基本数据类型转成字符串
static String valueOf(int)
static String valueOf(double)
特殊:字符串和字节数组在转换过程中,是可以指定编码表
看一个实例:
class StringMethodTest
{
public static void main(String[] args)
{
sop("("+myReverse(" df ss ")+")");
sop("("+myReverse(" df ss ",2,4)+")");
}
//练习,将字符串中的某两个位置间的字符反转(含头不含尾)
public static String myReverse(String str,int x,int y)
{
//字符串变成字符数组
char[] ch=str.toCharArray();
//反转数组
reverse(ch,x,y);
//将数组变成字符串
return new String(ch);
}
//练习二,将字符串反转
public static String myReverse(String str)
{
/*******方式一******
if(str!=null)
{
char[] ch=new char[str.length()];
int j=0;
for(int i=str.length()-1;i>=0;i--)
{
ch[j]=str.charAt(i);
j++;
}
return new String(ch);
}
return null;
*/
/*****************方式二******************/
//思路:
//1、将字符串变成数组
//2、对数组反转
//3、将数组变成字符串
//字符串变成字符数组
char[] ch=str.toCharArray();
//反转数组
reverse(ch,0,ch.length);
//将数组变成字符串
return new String(ch);
/***********方式三****************/
//return myReverse(str,0,str.length());
}
//反转数组
public static void reverse(char[] arr,int x,int y)
{
for(int start=x,end=y-1;start<end;start++,end--)
{
//数组中两个元素互换位置
swap(arr,start,end);
}
}
//数组中的两个元素位置互换
public static void swap(char[] arr,int x,int y)
{
char temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
4、替换
String replace(char oldchar,char newchar)
String replace(char oldString,char newString)
应用实例:
class StringMethodTest
{
public static void method_replace()
{
String s="hello java";
String s1=s.replace('a','n');
String s2=s.replace("java","world");//将java替换为world
sop(s);
sop(s1);
sop(s2);
}
public static void main(String[] args)
{
method_replace();
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
5、切割
String[] split();
public static void method_split()结果:
{
String s="zs,ls,ww,zl";
String[] arr=s.split(",");
for(int x=0;x<arr.length;x++)
{
sop(arr[x]);
}
}
6、子串
String substring(int begin);//从指定位置开始到结尾,如果角标不存在,会出现字符串角标越界异常
String substring(int begin,int end);//从指定位置到另一个指定位置,包含头不包含尾
如下:
public static void method_sub()
{
String s="asfafasd";
sop(s.substring(2));
sop(s.substring(2,3));
}
7、转换
7、1 将字符串转成大写或者小写
String toUpperCase();
String toLowerCase();
7、2 将字符串两端的多个空格去除
String trim()
7、3 对两个字符串进行自然顺序的比较
int compartTo(String)
public static void method_7()
{
String str=" hello JAVA ";
sop(str.toUpperCase());//转成大写
sop(str.toLowerCase());//转成小写
sop(str.trim());//将字符串两端的多个空格去除
}
结果:
看下面的例子:
class StringMethodTest
{
public static void main(String[] args)
{
sop(getMaxSubString("ddajavaklldadf","adfjavad"));
}
//获取两个字符串中最大相同子串。
//思路:
//1、将短的那个子串按照长度递减的方式获取到。
//2、将每次获取到的子串去长串中判断是否包含,如果包含,则找到
public static String getMaxSubString(String str,String key)
{
//外循环为循环次数
for(int x=0;x<key.length();x++)
{
//子串从最长长度开始
for(int y=0,z=key.length()-x;z!=key.length()+1;y++,z++)
{
String temp=key.substring(y,z);
if(str.contains(temp))
return temp;
}
}
return "";
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
StringBuffer
StringBuffer 是字符串缓冲区
是一个容器
特点:
1、长度是可变化的。
2、可以直接操作多个数据类型
3、最终会通过toString方法变成字符串
什么时候使用StringBuffer?
当数据类型不确定,个数不确定,最终要变成字符串的时候可以用缓冲区StringBuffer
1、存储
StringBuffer append();将指定的数据作为参数,添加到已有数据的结尾处。
StringBuffer insert(int index,数据):可以将数据插入指定index位置
2、删除
StringBuffer delete(start,end);删除缓冲区中的数据,含头不含尾
StringBuffer deleteCharAt(index);删除指定位置的字符
3、获取
char charAt();
int indexOf(char ch);
int lastIndexOf(char ch);
String substring(int start,int end);
4、修改
StringBuffer replace(int start,int end,String str)
void setCharAt(int index,char ch);修改指定位置的字符
5、反转
StringBuffer reverse();
6、将缓冲区中指定数据存储到指定字符数组中
void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin)
class StringBufferDemo
{
public static void main(String[] args)
{
//add();
//new StringBufferDemo().method_Del();
//method_update();
method_getChars();
}
public static void method_getChars()
{
StringBuffer sb=new StringBuffer("adfrgrf");
char[] chs=new char[6];
sb.getChars(1,4,chs,1);
for(int x=0;x<chs.length;x++)
{
sop("chs["+x+"]="+chs[x]);
}
}
//修改
public static void method_update()
{
StringBuffer sb=new StringBuffer("asdfdf");
//替换
sb.replace(1,3,"java");
sop(sb);
//修改指定位置的字符
sb.setCharAt(2,'q');
sop(sb);
}
//删除
public void method_Del()
{
StringBuffer sb=new StringBuffer("abcdefghijklmn");
sop(sb);
//删除
sb.delete(2,4);
sop(sb);
//删除指定位置的字符
sb.deleteCharAt(2);//sb.delete(2,3);
sop(sb);
//清空
sb.delete(0,sb.length());
sop(sb);
}
//添加
public static void add()
{
StringBuffer sb=new StringBuffer();
sb.append("af").append(true).append(23);
sop(sb);
//向StringBuffer中指定位置插入字符串
sb.insert(2,"www");
sop(sb);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
在JDK1.5版本之后出现了StringBuffer。
StringBuffer是线程同步,多线程时使用
StringBuilder是线程不同步的 ,单线程时使用
将StringBuilder的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用StringBuffer
以后开发建议使用StringBuilder
基本数据类型对象包装类。
byte Byte
short Short
int Integer
long Long
boolean Boolean
float Float
double Double
char Character
基本数据类型对象包装类的最常见作用,就是用于基本数据类型和字符串类型之间做转换。
基本数据类型转字符串
基本数据类型+""
基本数据类型.toString(基本数据类型值)
eg:Integer.toString(34);//将34整数变成"34"
字符串转成基本数据类型
方式一:
Integer.parseInt("123");
xxx a=Xxx.parseXss("数据");
方式二:
Integer i=new Integer("123");
int num=i.intValue();
十进制转成其他进制
toBinaryString(); 二进制
toHexString(); 十六进制
toOctalString(); 八进制
其他进制转成十进制
static int parseInt()
实例代码:
class IntegerDemo结果:
{
public static void main(String[] args)
{
trans();
}
public static void trans()
{
//十进制转十六进制
sop(Integer.toHexString(60));
//十进制转二进制
sop(Integer.toBinaryString(-6));
//十进制转八进制
sop(Integer.toOctalString(50));
int x=Integer.parseInt("110",2);//将数据转换成指定进制,默认是十进制
sop(x);
sop(Integer.parseInt("3c",16));/<span style="font-family: Arial, Helvetica, sans-serif;">/将数据转换成十六进制</span>
}
//打印
public static void sop(Object obj)
{
System.out.println(obj);
}
}