目录:
- 1.字符串 (String)
- 2.new String对象 和 不new String对象时内存分析:
- 2.1 不new String对象时内存分析
- 2.2 new String对象时内存分析
- 3.以下程序一共创建了几个对象?
- 4.String类中常用“构造方法”
- String( )
- String(byte [ ] b)
- String( byte [ ] b ,int offset ,int length )
- String( char [ ]c )
- String( char [ ]c ,int offset ,int length )
- 5.String类中常用“方法”
- char charAt( int index)
- int compareTo( String s )
- boolean contains( CharSequence c )
- boolean endsWith( String s )
- boolean startsWith( String s )
- boolean equals( Object o )
- boolean equalsIgnoreCase( String s)
- byte[ ] getBytes(String s)
- int indexOf( String s )
- int lastindexOf( String s )
- boolean isEmpty( )
- int length( )
- 面试题 :判断“数组长度”和“字符串长度”不一样
- String replace( CharSequence target, CharSequence replacement )
- String[ ] split( String s )
- String substring( int beginIndex)
- String substring( int beginIndex , int endIndex)
- char[ ] toCharArray( )
- String toUpperCase( )
- String toLowerCase( )
- String trim( )
1.字符串 (String)
JDK中内置的一个类: Java.lang.String。
String表示字符串类型,属于引用数据类型,不属于基本数据类型。。
在java中用双引号括起来的的都是String对象,都存储在“字符串常量池”中。例如”abc“ 、”abcde“,这两个都是字符串。
String字符串是不可变的,也就是说”abc“ 自出生到死亡,是不可变的,不能变成”abcd“,也不能变成“ab”
字符串存储“方法区” 中的 “字符串常量池”中。
(把数据放在字符串常量池中的原因: 字符串使用很频繁)例子1如:
/** * s1是对象的引用,s1的内存空间在“栈”的 “main方法栈帧”中,s1存放的是这个对象的“内存地址” * 这个“内存地址”指向"方法区"中的"字符串常量池"中的“"abcdef"对象 * * 同时s1是个局部变量 (该变量在main方法中) */ String s1 = "abcdef"; // 字符串是不可变的 //这里的 "abcdef" 没发生改变,所以没必要新建,直接从字符串常量池中获得 "abcdef"对象即可。 //把数据放在字符串常量池的原因: 字符串使用很频繁 // "xy" --- 在字符串常量池中新建了一个String对象 // "abcdef" 和 "xy" 相结合,形成了一个新的字符串 “abcdefxy”,存放在字符串常量池中 String s2 = "abcdef" + "xy"; //此时字符串常量池中有三个字符串对象 //用new对象的方式来创建字符串对象 //双引号括起来的字符串都在“字符串常量池”中有一份 //new对象时会在“堆内存”中开辟空间 //对内存中的String对象也是指向“字符串常量池”中的“xy” // new String("xy"); 对象的“内存地址”赋给了 s3 //s3是对象的引用,在内存中位置为“栈”中“main方法栈帧”中,存储的是其对象的内存的内存地址,同时“堆内存”中的该对象指向“字符串常量池”中“xy ” String s3 = new String("xy"); //在堆内存中开辟空间
上述代码中(例子1)的内存图:
例子2如:
public class User { private int id; private String name; public User() { } public User(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public String getName() { return name; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public static void main(String[] args) { //在“堆内存”中会存储一个“User对象” //“张三”这个值传最终传给 String name //在堆内存中有一个 “String name” ,其保存的是 “张三”这个字符串常量的“内存地址”, 这个“内存地址”指向“字符串常量池”中的“张三”对象 // name变量中存的是 “张三”这个对象的内存地址 User user = new User(101, "张三"); // "张三"存储在“字符串常量池”中 /** * User user 中的user的对象的引用,其的内存空间为“栈”的“main方法栈帧”中,其中 * 存储的是该对象的“内存地址” * 该“内存地址”指向“堆内存中的”的User对象 */ } }
上述代码(例子2)中的内存图:
2.new String对象 和 不new String对象时内存分析:
2.1 不new String对象时内存分析
//String s1 是一个变量 // s1是对象的引用 : 其的内存空间在“栈”的“main方法栈帧”中,其存储的内容为 "Hello"对象的内存地址 //这个内存地址指向 "Hello" 对象 //"Hello" 存储在“字符串常量池”中 String s1 = "Hello"; //所以第一个"Hello" 不会新建,直接拿来就行(因为这个对象已经存在了) // s2中存的也是同一个"Hello" 对象的内存地址 String s2 = "Hello"; /* 对于对象引用类型:“==”比较的是对象的内存地址 对于基本类型数据,“==”其实比较的是它的值 */ //此处的 == 号比较的是内存地址 System.out.println(s1==s2); //true (两者都指向同一对象,内存地址一样)
上述代码的内存图:
2.2 new String对象时内存分析
//创建了两个String对象 /* String x : 是一个“变量”, 其的内存空间为“栈”中的“main方法栈帧”,存储的是new String的 “内存地址” (new String的内存地址赋给 x) */ // new String()对象的内存空间在“堆内存”中,该对象存储的"xyz"对象的“内存地址” String x = new String("xyz"); //在“字符串”常量池中有“xyz”对象 //每new一次就会在“堆内存”里多一个对象 //此处 new String()对象的内存空间在“堆内存”中,但其的所在内存地址肯定不等于“上一个new的对 象”,该对象存储的"xyz"对象的“内存地址” String y = new String("xyz"); //但这个两个new String()对象中存放的同一个"xyz"对象的"内存地址" /** 对于对象引用类型:“==”比较的是对象的内存地址 对于基本类型数据,“==”其实比较的是它的值 */ //false (两者都指向不同的new String()对象,这两个对象内存地址不一样) System.out.println(x==y); //所以: 想要比较两个字符串是否相等,要用.equals()方法 //String重写了.equals()方法,让其判断两个“字符串的值”是否相等 System.out.println(x.equals(y)); //true
上述代码的内存图:
3.以下程序一共创建了几个对象?
//以下程序一共创建了几个对象
String s1 = new String("hello");
String s2 = new String("hello");
/**
* 一共3个对象:
*字符串常量池中1个“hello”对象。
*堆内存中有两个String对象
*/
4.String类中常用“构造方法”
- String s =“xxx” : 创建字符串对象最常用的方式
/** * 创建“字符串对象”最常用的一种方式 */ String s1 = "hello world!"; /* s1保存的是 "hello world!"对象的内存地址, 按理说以下应输出一个内存地址 但输出了一个字符串,说明String重写了toString()方法 */ System.out.println(s1); // helloWorld System.out.println(s1.toString()); // helloWorld
String( )
//无参构造方法
String s = new String();
String(byte [ ] b)
/**
* 常用的构造方法
*/
byte[] bytes = {97, 98, 99};
String s2 = new String(bytes); //将“字节型数组”转换为“字符串对象”
/*
s2保存的是新new的String对象的在“堆内存”中的“内存地址”
按理说以下应该输出该String对象的内存地址 (因为不重写toString的话,输出的是内存地址)
但却输出了一个字符串(abc/字符串本身),说明String重写了toString()方法
*/
System.out.println(s2); //abc
String( byte [ ] b ,int offset ,int length )
- String(byte [ ] b ,int offset ,int length) : String(字节数组 ,数组元素下标的开始位置 ,长度)
byte[] bytes = {97, 98, 99,100,101}; String s3 = new String(bytes,2,3); System.out.println(s3); //cde
String( char [ ]c )
char [] chars ={'我','是','中','国','人'};
//将char数组转换为 String字符串
String s = new String(chars);
System.out.println(s); //我是中国人
String( char [ ]c ,int offset ,int length )
char [] chars ={'我','是','中','国','人'};
//将char数组中“指定范围”的字符转换为字符串
String s = new String(chars,2,3);
System.out.println(s); //中国人
5.String类中常用“方法”
char charAt( int index)
String s = "中国人"; //“中国人”是一个字符串String对象,只要是对象就能调用方法。
//返回指定索引处的char值
char c = s.charAt(1);
System.out.println(c); //国
int compareTo( String s )
int compareTo( String s ) : 按字典顺序比较两个字符串。该比较基于字符串中各个字符的 Unicode 值。
(比较“对应位置”上的字符的Unicode值的大小,一个一个的比较,直到分出大小为止)如果要比较的两个字符相等,返回值为0;
如果前面字符串的Unicode值 > 后字符串的Unicode值,返回值为一个大于0的数。
如果前面字符串的Unicode值 < 后字符串的Unicode值,返回值为一个小于0的数。
前后一致:返回值为0;
前大后小 : 返回值为一个大于0的数;
前小后大:返回值为一个小于0的数;字符之间之间的比较不能用 > < ,需要使用功能compareTo( )方法
例子如:
//比较“对应位置”上的字符的Unicode值的大小 //如: 比较a与a:相等; 比较b与b:相等; 比较c与c:相等; 返回值为0 System.out.println("abc".compareTo("abc")); // 0 System.out.println("abcd".compareTo("abce")); // (前小后大: )一个小于0的值 :-1 System.out.println("abce".compareTo("abcd")); // (前大后小: )一个大于0的值 : 1 System.out.println("abcd".compareTo("abcd")); // 0 //如: 比较a与a:相等; 比较b与b:相等; 比较c与c:相等; d与空白: d大: 前大后小 : 返回值为1 System.out.println("abcd".compareTo("abc")); // (前大后小 :)一个大于0的数 : 1 System.out.println("abcd".compareTo("abcdef")); // (前小后大 :)一个小于0的值 :-2
boolean contains( CharSequence c )
判断前面的字符串是否包含后面的子字符串。
返回值为boolean类型。
// 判断前面的字符串是否包含后面的子字符串。 boolean contains1 = "HelloWorld.java".contains(".java"); boolean contains2 = "http://www.baidu.com".contains("https://"); System.out.println(contains1);//true System.out.println(contains2);//false
boolean endsWith( String s )
判断“当前字符串”是否以“某个字符串”结尾
返回值为boolean类型。
//判断“当前字符串”是否以“某个字符串” "结尾" System.out.println("test.txt".endsWith(".java")); //false System.out.println("test.txt".endsWith(".txt")); //true System.out.println("abacaseihsuwksss".endsWith("sss")); //true
boolean startsWith( String s )
判断“当前字符串”是否以“某个字符串” 开始
返回值为boolean类型。
//判断“当前字符串”是否以“某个字符串” "开始" System.out.println("http://www.baidu.com".startsWith("http://")); //true System.out.println("http://www.baidu.com".startsWith("https://")); //false
boolean equals( Object o )
判断两个字符串是否相等
//判断两个字符串是否相等 System.out.println("abc".equals("abc")); //true System.out.println("aaa".equals("bbb")); //false
boolean equalsIgnoreCase( String s)
判断两个字符串是否相等,并且同时忽略大小写.
//判断两个字符串是否相等,并且同时忽略大小写 System.out.println("ABC".equalsIgnoreCase("abc")); //true System.out.println("AB".equalsIgnoreCase("abc")); //false
byte[ ] getBytes(String s)
将“字符串”转换为“字节数组”
//将“字符串”转换为“字节数组” String s = "Hello,World"; byte[] bytes = s.getBytes(); //遍历byte数组 for (int i = 0; i < bytes.length; i++) { System.out.println(bytes[i]); }
int indexOf( String s )
判断“某个子字符串”在“当前字符串”中 第一次 出现的索引/下标
(为 第一次 出现的字符串中的 第一个字符 的索引/下标)能找到则返回值为: 该索引,不能找到则返回值为 -1
例子如:
//判断“某个子字符串”在“当前字符串”中"第一次"出现的索引/下标 //能找到则返回值为: 该索引,不能找到则返回值为 -1 System.out.println("oracleJavaC++JavaoraclepythonC++".indexOf("Java")); //6 System.out.println("123abc123abc".indexOf("123")); // 0 System.out.println("123abc123abc".indexOf("11111")); //-1
int lastindexOf( String s )
判断“某个子字符串”在“当前字符串”中 最后一次 出现的索引/下标
(为 最后一次 出现的字符串中的 第一个字符 的 索引/下标)能找到则返回值为: 该索引,不能找到则返回值为 -1
例子如:
//判断“某个子字符串”在“当前字符串”中"最后一次"出现的索引/下标 //能找到则返回值为: 该索引,不能找到则返回值为 -1 System.out.println("JavaC++JavaoraclepythonJava".lastIndexOf("Java")); //23 System.out.println("123abc123abc".lastIndexOf("123")); // 6 System.out.println("123abc123abc".lastIndexOf("11111")); //-1
boolean isEmpty( )
判断某个字符串是否为“空字符串”
//判断某个字符串是否为“空字符串 String s1 = ""; String s2 = "123"; System.out.println(s1.isEmpty()); //true System.out.println(s2.isEmpty()); //false
int length( )
获取字符串的“长度”
//获取字符串的“长度” System.out.println("abc".length()); // 3
面试题 :判断“数组长度”和“字符串长度”不一样
判断“数组长度”是length( )属性,判断“字符串长度”是length( )方法
System.out.println("abc".length()); // .length()方法 int[] a = {1, 2, 3}; for (int i = 0; i < a.length; i++) { // .length属性 System.out.println(a[i]); }
String replace( CharSequence target, CharSequence replacement )
用”新字符“替换”老字符“,返回一个“新的String字符串”
//用”新字符“替换”老字符“,返回一个“新的String字符串” String newString1 = "http://www.baidu.com".replace("http://", "https://"); System.out.println(newString1); //https://www.baidu.com String newString2 = "name=zhangsan&password=123&word=123&age=20".replace("=", ":"); System.out.println(newString2); //name:zhangsan&password:123&word:123&age:20
String[ ] split( String s )
根据给定"字符"/“正则表达式”的匹配拆分此字符串。
//根据给定"字符"/“正则表达式”的匹配拆分此字符串。 String[] split = "1980-10-11".split("-"); for (int i = 0; i < split.length; i++) { System.out.println(split[i]); }
String substring( int beginIndex)
截取 “指定索引之后” 的字符,返回值为一个字符串。
//截取字符串 System.out.println("http://www.baidu.com".substring(7)); //www.baidu.com
String substring( int beginIndex , int endIndex)
截取 ”开始索引”到“结束索引-1”范围内 的字符,返回值为一个字符串
//截取”开始索引”到“结束索引-1”范围内的字符,返回值为一个字符串 System.out.println("http://www.baidu.com".substring(11,16)); //baidu
char[ ] toCharArray( )
将字符串转换为char数组
//将字符串转换为char数组 String str = "我是中国人呢"; char[] chars = str.toCharArray(); for (int i = 0; i < chars.length; i++) { System.out.println(chars[i]); }
String toUpperCase( )
转换为 大写
//转换为大写 String str3 = "klaghlig"; String str4 = str1.toUpperCase(); System.out.println(str4); //KLAGHLIG
String toLowerCase( )
转换为 小写
//转换为小写 String str1 = "AFSGGAsgy"; String str2 = str1.toLowerCase(); System.out.println(str2); //afsggasgy
String trim( )
去除字符串 “前后” 的“空白"
//去除字符串“前后”的“空白" String str1 = " 我是 中国人 "; String str2 = str1.trim(); System.out.println(str2); //我是 中国人