目录标题
1字符串的存储原理
1.1String的理解
关于Java JDK中内置的一个类:java.lang.String
1.String表示字符串类型,属于引用数据类型,不属于基本数据类型
2.在java中随便使用双引号括起来的都是String对象。例如:“abc”,“def”,“hello world”
3.java中规定,双引号括起来的字符串,是不可变的,也就是说"abc"自出生到死亡,不可变,不能变成“ABCd”
4.在JDK中双引号括起来的字符串,例如:“abc”,"def"都是直接存储在“方法区”的"字符串常量池”当中的
为什么SUN公司把字符串存储在一个“字符串常量池”当中呢,因为字符串在实际开发中使用太频繁。为了执行效率
所以把字符串放到了方法取得字符串常量池中
1.2代码展示
package com.power.javase.string;
public class StringTest01 {
public static void main(String[] args) {
//这两行代码表示底层创建了3个字符串对象,都在字符串
String s1 = "abcdef";
String s2 = "abcdef" + "xy";
//这是使用new的方法创建的字符串对象。这个代码中的“xy"是从哪里来的?" +
//凡是双引号括起来的都是在字符串常量池中中有一份
//new对象的时候一定在堆内存当中开辟空间。
String s3 = new String("xy");
}
}
1.3内存原理图
2.分析字符串的存储原理
主要为了探究内存结构原理图写的user类和测试类
2.1代码展示
2.1.1简单写了一个User类
package com.power.javase.string;
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 void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.1.2简单写了一个测试类UserTest
package com.power.javase.string;
public class UserTest {
public static void main(String[] args) {
User u = new User(110,"张三");
}
}
哦,对了,这个题目没有运行结果,主要是问了研究它的内存结构图
2.2内存原理图
3创建了几个对象
3.1代码展示
3.1.1注意
注意:我们在编写字符串equals方法的时候,注意前面最好是字符串,这样可以避免可能出现的空指针异常
//String k = new String("testString");
String k = null;
//"testString"这个字符串后面可以加"."吗?
//因为"testString"是一个String字符串对象。只要是对象都能调用方法
System.out.println("testString".equals(k));//建议使用这种方法,因为这个可以避免空指针异常
System.out.println(k.equals("testString")); //存在空指针异常的风险
3.1.2代码展示
package com.power.javase.string;
public class StringTest02
{
public static void main(String[] args) {
String s1 = "hello";
//"hello"是存储在方法去的字符串常量池中
//所以这个"hello"不会新建(因为这个对象已经存在了)
//分析结果是true还是false?
// == 双等号比较的是变量中保存的内存地址
String s2 = "hello";
System.out.println(s1 == s2); //true
String x = new String();
String y = new String();
//分析结果是true还是false?
// == 双等号比较的是变量中保存的内存地址
System.out.println(x == y); //false
//通过这个案例的分析,我们知道,字符对象之间的比较不能使用"=="
//"==" 不保险,应该调用String的equals方法
//String类已经重写了equal方法,以下的equals方法调用的是String重写之后的equal方法
System.out.println(x.equals(y)); //true
}
}
3.2执行结果
3.3内存原理图
4.String面试题:一共创建了几个对象?
答案是:3个
package com.power.javase.string;
/*
分析以下程序,一共创建了几个对象
*/
public class StringTest03 {
/*
一共三个对象
方法区字符串常量池中有一个:"hello"
堆内存当中有两个String,一共三个
*/
String s1= new String("hello");
String s2= new String("hello");
}
5.String类已经重写了toString()方法
注意: //s1这个变量中保存的是一个内存地址
//按说以下应该输出一个地址
//但是输出一个字符串,说明String类已经重写了toString()方法
String里面的构造方法
- 第一个:String s = new String("")
- 第二个:String s = “”;最常用
- 第三个:String s = new String(char 数组);
- 第四个:String s = new String(char数组,起始下标,长度);
- 第五个:String s =new String (byte数组);
- 第六个:String s = new String(byte数组,起始下标,长度);
5.1代码展示
package com.power.javase.string;
public class StringTest04 {
//创建字符串对象最常用的一种方式
public static void main(String[] args) {
String s1 = "hello world";
//s1这个变量中保存的是一个内存地址
//按说以下应该输出一个地址
//但是输出一个字符串,说明String类已经重写了toString()方法
System.out.println(s1);//hello world
System.out.println(s1.toString());//hello world
//这里只掌握常用的构造方法
byte[] bytes = {97,98,99}; //97是a,98是b,99是c
String s2 = new String(bytes);
//前面说过,输出一个引用的时候,会自动给调用toString()方法,默认Object的话,会自动输出对象的内存地址
//通过输出结果我们得出一个结论:String类已经重写了toString()方法
//输出字符串对象的话,输出的不是对象的内存地址,而是字符串本身
System.out.println(s2.toString());//abc
System.out.println(s2);//abc
//String(字节数组,数组元素下标的起始位置,长度)
//将byte数组中的一部分转换成字符串
String s3 = new String(bytes,1,2);
System.out.println(s3); //bc
//将char数组全部转换成字符
char[] chars = {'我','是','中','国','人'};
String s4 = new String(chars);
System.out.println(s4);
//将char数组的一部分转换成字符串
String s5 = new String(chars,2,3);
System.out.println(s5);
String s6 = new String("helloworld!");
System.out.println(s6); //helloworld
}
}
5.2执行结果
6.String中常用的方法
package com.power.javase.string;
/*
int compareTo(String anotherString)
按字典顺序比较两个字符串。
*/
public class StringTest05 {
public static void main(String[] args) {
//String类当中的常用方法
//1.char charAt(int index)
char c = "中国人".charAt(1); //中国人是一个字符串String对象,只要是对象就能”点.“
System.out.println(c); //国
//2.compareTo(String anotherString)
int result = "abc".compareTo("abc");
System.out.println(result); //0(等于0) 10-10=0
int result2 = "abcd".compareTo("abce");
System.out.println(result2); //-1(小于0)8-9=-1
int result3 = "abce".compareTo("abcd");
System.out.println(result3); //1(大于0)9-8=1
//2(掌握)拿着字符串第一个字母和后面的字符串第一个比较
int result4 = "xyz".compareTo("yxz");
System.out.println(result3); //-1
//3(掌握).判断前面的字符串是否包含后边
//boolean contains(CharSequence s)当且仅当此字符串包含指定的char值序列时才返回true。
System.out.println(".hello.java".contains(".java")); //true
System.out.println("http://www.baidu.com".contains("https")); //false
//4(掌握).boolean endsWith(String suffix)测试此字符串是否以指定的后缀结尾。
System.out.println("test.txt".endsWith(".java")); //false
System.out.println("test.txt".endsWith(".txt")); //true
System.out.println("ahidjwqiwedjskaIss".endsWith("ss")); //true
//5(掌握)boolean equals(Object anObject) 将此字符串与指定对象进行比较。
//比较两个字符串必须使用equals,不能使用"=="
System.out.println("abc".equals("abc")); //true
//6(掌握) boolean equalsIgnoreCase(String anotherString)
//将此 String与其他 String比较,忽略大小写。
System.out.println("abc".equalsIgnoreCase("abC"));//true
//7(掌握)byte[] getBytes()
//将字符串对象转换成字节数组
byte[] bytes = "abcdef".getBytes();
for(int i = 0; i < bytes.length;i++){
System.out.println(bytes[i]);
}
//8(掌握)indexOf(String str)
//判断某个字符串在当前字符串中第一次出现粗话的索引(下标)
System.out.println("jeidskajavadjiqeksaxz".indexOf("java")); //6
//9(掌握)isEmpty()
//判断某个字符串是否为空字符串
//String s = "";
String s = "a";
System.out.println(s.isEmpty());
//10(掌握).int length()
//面试题:判断数组长度和判断字符串长度不一样
//判断数组长度是length,判断字符串长度是length()方法
System.out.println("abc".length()); //3
//11(掌握).lastIndexOf(String str)
//返回指定子字符串最后一次出现的字符串中的索引。
System.out.println("oracjavac++javac#cphpjavapython)".lastIndexOf("java")); //21
//12(掌握)String replace(CharSequence target, CharSequence replacement)
//替换
//String 的父接口是:CharSequence
String newString = "http://www.baidu.com".replace("http://","https");
System.out.println(newString);
//把以下字符串中的“=”替换成“:”
String newString2 = "name=zhangsan==yang=eh=53".replace("=",":");
System.out.println(newString2); //name:zhangsan::yang:eh:53
//13.(掌握)String[] split(String regex)
//将此字符串分割为给定的 regular expression的匹配。拆分字符串
String[] ymd = "1980-10-11".split("-");//1980-10-11以"-"拆分
for(int i = 0;i < ymd.length;i++){
System.out.println(ymd[i]);
}
String param = "name=&zhangsan==yang=e&h=53";
String[] params = param.split ("&");
for(int i = 0; i < params.length;i++){
System.out.println(params[i]);
}
//14(掌握)boolean startsWith(String prefix)
//判断某个字符串是否以某个子字符串开始
System.out.println("http://www.baidu.com".startsWith("http")); //true
System.out.println("http://www.baidu.com".startsWith("https")); //false
//15(掌握)String substring(int beginIndex),参数是起始下标
//截取字符串
System.out.println("http://www.baidu.com".substring(7)); //www.baidu.com
//16(掌握)String substring(int beginIndex, int endIndex)
//beginIndex包括,endIndex不包括
System.out.println("http://www.baidu.com".substring(7,10)); //www
//17(掌握)char[] toCharArray()
//将此字符串转换为新的字符数组。
char[] chars = "我是中国人".toCharArray();
for(int i = 0;i < chars.length;i++){
System.out.println(chars[i]);
}
//18.(掌握) String toLowerCase()
//将所有在此字符 String使用默认语言环境的规则,以小写。
System.out.println("ABHEDKSUhikf".toLowerCase());
//19(掌握)String toUpperCase()
//将所有在此字符 String使用默认语言环境的规则大写。
System.out.println("ABHEDKSUhikf".toLowerCase());
//20(掌握)String trim()
//去除前后空白
System.out.println(" hello world ".trim());
//21(掌握).String中只用一个方法是静态的,不需要new对象
//这个方法叫做ValueOf
//作用:将“非字符串”转换成字符串
//String s1 = String.valueOf(true);
//String s1 = String.valueOf(100);
//String s1 = String.valueOf(3.14);
String s1 = String.valueOf(new Customer());
//System.out.println(s1); //没有重写toString()方法之前是对象内存地址com.power.javase.string.Customer@1b6d3586
System.out.println(s1);
//研究一下println()方法的源码?
System.out.println(100);
System.out.println(3.14);
System.out.println("hello");
System.out.println(true);
Object obj = new Object();
//通过源代码可以看出:为什么为什么输出一个引用的时候,会调用toString()方法!!
//本质上System.out.println(obj); 这个方法在输出任何数据的时候都是先转成字符串,再输出
System.out.println(obj);
System.out.println(new Customer()); //输出的时候会自动调用toString()方法,在Customer中已经重写这个方法了
System.out.println(100);
}
}
class Customer{
//重写toString()方法
public String toString(){
return "我是一个VIP客户";
}
}