一、String类
1、概述:Java中一个特殊的类,用于描述字符串。
2、String类的源码声明:
public final classString
extends Object
implements Serializable,Comparable<String>,CharSequence
含义说明:String类被final所修饰,代表这个类不可以有子类,里面的功能方法也不能被覆写。
3、特点:
①、Java中的所有字符串类型的值都是String类的实例对象。
字符串:用双引号" "扩起来的部分。
②、字符串一旦初始化就不可以被改变。【非常重要】
如果改变了,则改变的肯定是String的引用地址。
4、String类的实例化方式:
①、直接赋值:String s = “abc”;
②、调用String类的构造方法:String s = new String(“abc”);
面试题:
String s1 = "abc";
String s2 = new String("abc");
请问s1和s2有什么区别?
答:s1在内存中有一个对象。
s2在内存中有两个对象。
5、字符串比较示例:
示例代码:
class StringMethodDemo
{
public static void main(String[] args)
{
String s1 = "abc";
String s2 = new String("abc");
String s3 = "abc";
System.out.println(s1==s2); //结果为:false
System.out.println(s1==s3); //结果为:true。
System.out.println(s1.equals(s2)); //结果为:true。
}
}
①、为什么s1==s2的结果为false?
答:因为s1和s2是两个不同的对象,而它们的内存地址值是不一样的,所以比较之后返回的结果是false。
②、为什么s1==s3的结果为true?
答:字符串存在于内存的常量池当中。
当s1初始化完了之后,s3再进行初始化的时候发现字符串“abc”已经在常量池中存在了,所以s3就不会再独立开辟内存空间了。因为再开辟空间的话,比较浪费内存资源。
③、为什么s1.equals(s2)的结果为true?
答:因为字符串对象s1和s2的内容相同。
String类覆写了Object类中的equals方法,而该方法是用于判断字符串内容是否相同。它们的内容都是"abc",所以返回结果是true。
二、字符串的常见操作
1、获取
①、字符串中包含的字符个数,也就是字符串的长度。
int length():获取长度。
②、根据指定位置获取该位置上的某个字符。
char charAt(int index)
③、根据字符获取该字符在字符串中的位置。
int indexOf(int ch):返回的是ch在字符串中的第一次出现的位置。
int indexOf(int ch,int fromIndex):从fromIndex指定位置开始,获取ch在字符串中出现的位置。
int indexOf(String str):返回的是str在字符串中的第一次出现的位置。
int indexOf(String str,int fromIndex):从fromIndex指定位置开始,获取str在字符串中出现的位置。
intlastIndexOf(int ch):反向索引指定的字符在字符串中出现的位置。
代码示例:
public static void method_get()
{
String str = "abcdeakpf"; //定义一个字符串。
//获取字符的长度
sop(str.length());
//根据索引获取字符。
sop(str.charAt(4)); //当访问到字符串中不存在的角标时会发生StringIndexOutOfBoundsException异常。
//根据字符获取索引。
sop(str.indexOf('m',3)); //如果没有找到,返回-1。
//反向索引一个字符出现的位置。
sop(str.lastIndexOf("a"));
}
2、判断
①、字符串中是否包含某一个字符。
boolean contains(str);
特殊之处:indexOf(str):可以索引str第一次出现的位置,如果返回-1表示该str不在字符串中存在。所以,也可以用于对指定字符串判断是否包含。
if(str.indexOf("aa")!=-1)
indexOf(str)的好处:而且该方法既可以判断,又可以获取出现的位置。
②、字符串中是否有内容。
boolean isEmpty(); 原理就是判断长度是否为0。
③、字符串是否是以指定内容开头。
boolean startsWith(str);
④、字符串是否是以指定内容结尾。
boolean endsWith(str);
⑤、判断字符串的内容是否相同。(覆写了Object类中的equals方法)
boolean equals(str);
⑥、判断内容是否相同,并忽略大小写。
boolean equalsIgnoreCase();
代码示例:
public static void method_is()
{
String str ="ArrayDemo.java"; //定义一个字符串。
sop(str.startsWith("Array")); //判断文件名称是否是Array单词开头。
sop(str.endsWith(".java")); //判断文件名称是否是.java的文件。
sop(str.contains("Demo")); //判断文件中是否包含Demo
sop(str.isEmpty()); //判断该字符串是否为空。
}
3、转换
①、将字符数组转成字符串。
构造函数:
String(char[] value)
String(char[]value,int offset,int count):将字符数组中的一部分转成字符串。
静态方法:
staticString copyValueOf(char[]);
staticString copyValueOf(char[] data,int offset,int count);
staticString valueOf(char[]);
②、将字符串转成字符数组。
char[]toCharArray();
③、将字节数组转成字符串。
String(byte[]value)
String(byte[]value,int offset,int count):将字节数组中的一部分转成字符串。
④、将字符串转成字节数组。
byte[] getBytes();
⑤、将基本数据类型转成字符串。
staticString valueOf(int)
staticString valueOf(double)
示例:3+""; //相当于:String.valueOf(3);
特殊:字符串和字符数组在转换过程中,是可以指定编码表的。
代码示例:
public static void method_trans()
{
char[] arr = {'a','b','c','d','e','f'};
//将字符数组转成字符串。
String s1 = new String(arr); //s=abcdef
String s2 = new String(arr,1,3); //s=bcd
<pre name="code" class="java"> System.out.println<span style="font-family: Arial, Helvetica, sans-serif;">("s="+s1);</span>
System.out.println("s="+s2);
String s3 = "zxcvbnm"; char[] chs = s1.toCharArray(); for(int x=0; x<chs.length; x++) {System.out.println("ch="+chs[x]);
}}
4、替换
String replace(char oldChar,char newChar);
代码示例:
public static void method_replace()
{
String s = "hello java";
String s1 = s.replace('q','n'); //如果要替换的字符不存在,返回的就是原字符串。
String s2 = s.replace("java","world");
sop("s="+s);
sop("s1="+s1);
sop("s2="+s2);
}
5、切割
String[]split(regex);
代码示例:
public static void method_split()
{
String s = "zhangsan,lisi,wangwu";
String[] arr = s.split(",");
for(int x=0; x<arr.length; x++)
{
sop(arr[x]);
}
}
6、子串(获取字符串中的一部分)
Stringsubstring(beginIndex);
Stringsubstring(beginIndex,endIndex);
代码示例:
public static void method_sub()
{
String s = "abcdef";
sop(s.substring(2)); //cdef。从指定位置开始到结尾。
//注意:如果角标不存在,会出现字符串角标越界异常。
sop(s.substring(2,4)); //cd。包含头,不包含尾。
//截取整个字符串:s.substring(0,s.length);
}
7、转换、去除空格、比较
①、将字符串转换成大写或者小写。
String toUpperCase();
String toLowerCase();
②、将字符串两段的多个空格去除。
String trim();
③、对两个字符串进行自然顺序的比较。
int compareTo(string);
代码示例:
public static void method_7()
{
String s = " Hello Java ";
sop(s.toLowerCase());
sop(s.toUpperCase());
sop(s.trim());
String s1 = "acc";
String s2 = "aaa";
sop(s1.compareTo(s2)); //返回2。a=97,c=99,c-a=2,所以结果是2。
}
个人总结:
字符串比较就是在比较字符串里面每个字符代表的ASCII码数值。相等就返回0。
当前字符串(s1)和参数字符串(s2)对应位置上的字符的ASCII码值相减的结果就是比较之后返回的值。如果第一个比较的字符相同的话,就继续比较第二个字符,以此类推。
三、StringBuffer、StringBuilder
1、StringBuffer:字符串缓冲区,是一个容器。
2、作用:可以通过StringBuffer对字符串内容进行修改。
3、特点:
①、StringBuffer的长度是可变化的。(数组的长度是不可变化的)
②、可以直接操作多个数据类型。
③、可以通过toString方法将数据变成字符串。
④、被final修饰,不可以被继承,里面的方法也不可以被覆写。
4、什么时候使用StringBuffer?
当数据类型和数据的个数不确定,而且最终要变成字符串的时候,使用缓冲区是最合适的。
5、StringBuffer类的常用操作:
①、添加/存储
StringBuffer append():将指定的数据做为参数添加到已有数据的结尾处。
StringBuffer insert(index,数据):可以将数据插入到指定index位置。
代码示例:
public static void method_add()
{
StringBuffer sb = new StringBuffer();
sb.append("abc").append(true).append(34);
StringBuffer sb1 = sb.append(34);
sb.insert(1,"qq"); //aqqbctrue34
sop(sb.toString()); //abctrue34
sop(sb1.toString());
}
②、删除
StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end。
StringBuffer deleteCharAt(index):删除指定位置的字符。
代码示例:
public static void method_del()
{
StringBuffer sb = new StringBuffer("abcde");
//sb.delete(1,3); //ade
//sb.delete(0,sb.length()); //清空缓冲区。
//sb.delete(2,3); //abde
sb.deleteCharAt(2); //abde
sop(sb.toString());
}
③、获取
char charAt(int index)
int indexOf(String str)
int lastIndexOf(String str)
int length()
String substring(int start,int end)
④、修改
StringBuffer replace(int start,intend,String str)
void setCharAt(int index,char ch);
代码示例:
public static void method_update()
{
StringBuffer sb = new StringBuffer("abcde");
//sb.replace(1,4,"java"); //ajavae
sb.setCharAt(2,'k');
sop(sb.toString()); //abkde
}
⑤、反转
StringBuffer reverse()
⑥、将缓冲区中的指定数据存储到指定字符数组中。
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
代码示例:
public static void otherMethod()
{
StringBuffer sb = new StringBuffer("abcdef");
char[] chs = new char[6];
sb.getChars(1,4,chs,1);
for(int x=0; x<chs.length; x++)
{
sop("chs["+x+"]="+chs[x]+";");
}
/*
输出结果是:
chs[0]= ;
chs[1]=b;
chs[2]=c;
chs[3]=d;
chs[4]= ;
chs[5]= ;
*/
}
6、StringBuilder
①、和StringBuffer的区别:
相同点:功能上StringBuilder和StringBuffer一样。(StringBuilder是StringBuffer的一个简易替换)
不同点:
StringBuffer是线程同步的,安全,效率低。
StringBuilder是线程不同步的,不安全,效率高。(可以通过加锁来达到安全目的)
注意:开发中建议使用StringBuilder,因为更高效。如果需要同步,建议使用StringBuffer。
小知识点:JDK升级的三个因素:
1、提高效率。
2、简化书写。
3、提高安全性。
四、包装类
1、包装类:将8种基本数据类型封装成类的形式,以便可以被创建对象。
2、好处:可以在包装类的对象中定义更多的功能方法操作相关数据。
3、包装类列表:
序 号 | 基本数据类型 | 包装类 |
1 | byte | Byte |
2 | short | Short |
3 | int | Integer |
4 | long | Long |
5 | float | Float |
6 | double | Double |
7 | char | Character |
8 | boolean | Boolean |
4、包装类的体系结构:
Object
|--Number
|--Byte
|--Short
|--Integer
|--Long
|--Float
|--Double
|--Character
|--Boolean
5、包装类的常见操作:
基本数据类型和字符串类型之间做转换:
①、基本数据类型转成字符串。
方式一(最简单的方式):基本数据类型+”” //例如:100+””
方式二:基本数据类型包装类.toString(基本数据类型值);
static String toString(int i) //例如:Integer.toString();
②、【最常用】字符串转成基本数据类型。
xxx a = Xxx.parseXxx(String str);
/*
示例:
静态调用方式:
int a = Integer.parseInt("123");
double d = Double.parseDouble("123.456");
boolean b = Boolean.parseBoolean("true");
对象调用方式:
Integer i = new Integer(“123”);
int num = i.intValue();
*/
6、(自动)装箱与拆箱
①、装箱:将一个基本数据类型变为包装类的过程。
②、拆箱:将一个包装类变为基本数据类型的过程。
装箱和拆箱代码示例:
class Demo
{
pubilc static void main(String[] args)
{
int x = 4;
Integer x = new Integer(x); //装箱。将基本数据类型变成包装类。
int temp = x.intValue(); //拆箱:将包装类变成基本数据类型。
}
}
③、自动装箱与拆箱:是JDK1.5版本的新特性。(简化了定义方式)
自动拆箱与装箱代码示例:
class Demo
{
public static void main(String[] args)
{
Integer x = 4; //自动装箱为Integer包装类型。
Float f = 3.14f; //自动装箱为Float包装类型。
int a = x; //自动拆箱为int基本数据类型。
float b = f; //自动拆箱为float基本数据类型。
}
}
特殊注意示例:
Integer m = 128;
Integer n = 128;
System.out.println("m==n:"+(m==n)); //结果为:false。因为128已经超出了byte类型表示的数值范围,所需需要重新在内存中开辟更多的空间。
Integer a = 127;
Integer b = 127;
System.out.println("a==b:"+(a==b)); //结果为true。因为a和b指向了同一个Integer对象。
/*
因为当数值在byte表示范围内时,对于新特性,如果数值已经在内存中存在,则不会再开辟新的空间。
*/