一. main方法中的String数组
1. main方法上面的“String[] args”有什么用?
JVM负责调用main方法的时候,会自动传一个String数组过来
public class mainTest {
//这个方法程序员负责写出来,JVM负责调用。JVM调用的时候一定会传一个String数组过来
public static void main(String[] args){
//JVM默认传递过来的这个数组对象的长度默认为0
//通过测试得出:args不是null
System.out.println("JVM给传递过来的String数组,他这个数组的长度是"+ args.length);
}
}
输出结果:

2. 那么数组什么时候里面会有值呢?
这个数组其实是留给用户的,用户可以在控制台上输入参数,这个参数自动会被转换成 String[] args。
例如这样运行程序:java ArrayTest abc def xyz
那么这个时候 JVM 会自动将 abc def xyz 通过空格的方式进行分离,分离完成之后,自动放入到 String[] args 数组当中。所以 main 方法上面的 String[] args 数组主要是用来接收用户输入参数的。
把 abc def xyz 转换成字符串数组:{“abc”," def", “xyz”}
3. main方法String参数的案例
模拟一个系统,假设这个系统要使用,必须输入用户名和密码。
public class Arraytest1 {
//用户名和密码输入到String[] args数组当中
public static void main(String[] args) {
if (args.length != 2){
System.out.println("使用该系统时请输入程序参数,参数包括用户名和密码信息,例如:zhangsan 123");
return;
}
//程序执行到此处说明用户确实提供了用户名和密码
//接下来应该判断用户名和密码
//取出用户名
String username = args[0];
String password = args[1];
//假设用户名是admin,密码是123的时候表示登录成功。其他一律失败
//判断两个字符串是否相等,需要使用equals方法
//if (username.equals("admin") && password.equals("123")){
//这样编写是不可以避免空指针异常的
//采取以下风格的代码,即使username和password都是null,也不会出现空指针异常
if ("admin".equals(username) && "123".equals(password)){
System.out.println("登录成功,欢迎" + username + "回来");
}
else{
System.out.println("验证失败,用户名不存在或密码不正确!");
}
}
}
输出结果
1、登录成功

2、登录失败


二. String字符串的存储原理
1. 关于Java中JDK中内置的String类
String表示字符串类型,属于引用类型,不属于基本数据类型。
在java中随便使用双引号括起来的都是String对象。例如:“abc”、”hello world!”等都是String对象
java中规定。双引号括起来的字母是不可变的。
在JDK中双引号括起来的字符串,是直接存储在 “方法区” 的“字符串常量池”当中的。
String s1 = "abc";
String s2 = "def" + " gh";
这两行代码表示在底层创建了三个字符串对象,都在字符串常量池中。
String s3 = new String ("xy");
- 一些代码运行的储存图
User user = new User(110,"张三")
储存原理:

String s1 = "hello";//hello储存在方法区的字符串常量池中
String s2 = "hello";
System.out.println(s1 == s2); //结果为true
String x = new String ("xyz");
String y = new String ("xyz");
System.out.println(x == y); //结果为false

==比较的是内存地址
三. 分析String创建多少对象(面试题)
分析以下程序一共创建几个对象
String s1 = new String ("hello");
String s2 = new String ("hello");
分析: 一共三个对象:方法区字符串常量池中有一个:”hello” 堆内存当中有两个String对象。 一共有三个。
四. String类的构造方法
1. 常用的String构造方法
1.创建字符串对象最常用的一种方式
String s1 = "hello world";
System.out.println(s1); //hello world
byte[] bytes = {97,98,99}; //97是a,98是b,99是c
String s2 = new String(bytes);
System.out.println(s2); //输出结果:abc
s1变量中保存的仅仅是一个内存地址,但是String类已经重写了toString()方法。
因为输出一个引用的时候,会自动调用toString方法,默认Object类的话,会自动输出对象的内存地址。
输出字符串对象的话,输出的不是对象的的内存地址,而是字符串本身
2.将byte数组的一部分转换成字符串
String s3 = new String(byte, 1 ,2)
System.out.println(s3); //输出结果:bc
String(字节数组,数组元素下标的起始位置,长度)
3. 将char数组全部转换成字符串
char[] chars = {'我','是','中','国','人'} ;
4. 将char数组一部分准换成字符串
String s = new String(chars,数组元素下标的起始位置,长度);
五. String类的常用方法
1. charAt
返回参数下标对应的字符
语法格式:char charAt(int index)
例如:
char c = "中国人".charAt(1);//“中国人”是个字符串String对象,只要是个对象就可以用
System.out.println(c);//输出结果:国
2. compareTo
比较字符串大小关系,字符串之间大小关系不能用><比较
前后一致:为0
前小后大:为-1
前大后小:为1
语法格式: int compareTo(String anotherString)
int result = "abc".compare("abc");
System.out.println(result);//输出结果:0
int result1 = "abcd".compare("abce");
System.out.println(result1);//输出结果:-1
int result3 = "abce".compare("abcd");
System.out.println(result3);//输出结果:1
3. contains
判断前面的字符串是否包含后面的子字符串。
语法格式:boolean contains(CharSequence s)
System.out.println("Helloworld.java"contains(".java"));//输出结果:true
System.out.println("http://www.baidu.com"contains("https://"));//输出结果:false
4. endWith
判断当前字符串是否以某个字符串结尾
语法格式:boolean endWith(String suffix)
System.out.println("text.txt".endWith(".java"));//输出结果:false
System.out.println("text.txt".endWith(".txt"));//输出结果:true
System.out.println("dsfasdfsadfsadfasss".endWith("ss"));//输出结果:true
5. starsWith
用法: 判断某个字符串是否以某个子字符串开始
语法格式:boolean starsWith(String prefix)
System.out.println("http://www.baidu.com"contains("http://"));//输出结果:true
System.out.println("http://www.baidu.com"contains("https://"));//输出结果:false
6. equals
比较两个字符串必须使用equals方法,不能使用== 老版本JDK调用了compareTo方法,新版本JDK并没有(JDK13)
语法格式:boolean equals(Object anObject)
7. getBytes
将字符串对象转换成字节数组
语法格式:byte[] getBytes()
byte[] bytes = "abcdef".getBytes();
for(int i =0 ; i < bytes.length ; i++){
System.out.println(bytes[i]);
}
运行结果:

8. indexOf
判断某个子字符串在当前字符串第一次出现处的索引(下标)
语法格式: int indexOf(String str)
System.out.println("oraclejavac++.netc#pythonphpjavaoraclec++".indexOf("java"));//输出结果:6
9. lastIndexOf
判断某个子字符串在当前字符串最后一次出现处的索引(下标)
System.out.println("oraclejavac++.netc#pythonphpjavaoraclec++".indexOf("java"));//输出结果:22
10. isEmpty
判断某个字符串是否为“空字符串”,底层源代码调用的应该是字符串的length()方法
String s = "a";
String s1 = "";
System.out.println(s.isEmpty());
System.out.println(s1.isEmpty());
输出结果:

11. length
判断数组长度是length属性,判断字符串长度是length方法
语法格式:int length()
12. replace
替换字符串
语法格式:String replace(CharSequence target, CharSequence replacement)
String newString = "http://www.baidu.com".replace("http://","https://")
System.out.println(newString);//输出结果:https://www.baidu.com
13. split
用法:拆分字符串
语法格式: String[] split(String regex)
String[] ymd = "1998-11-10".split("-");
for(int i = 0 ; i < ymd.length ; i++){
System.out.println(ymd[i]);
}
运行结果:

14. substring
用法 :截取字符串
语法格式: String substring(int begininIndex)
System.out.println("http://www.baidu.com".substring(7));//输出结果:www.baidu.com
语法格式: String substring(int begininIndex,int endIndex)
System.out.println("http://www.baidu.com".substring(7,10));//输出结果:www
重点: 左闭右开,不包括结束下标的字符
15. toCharArray
用法:将字符串转换为char数组
语法格式:char[] toCharArray()
char[] chars = "我是中国人".toCharArray();
for(int i = 0 ; i < chars.length ; i++){
System.out.println(chars[i]);
}

16. toLowerCase
用法:转换为小写
语法格式: String toLowerCase()
System.out.println("ABCdefgh".toLowerCase());

17. toUpperCase
用法:转换为大写
语法格式: String toLowerCase()
System.out.println("ABCdefgh".toLowerCase());

18. trim
用法:去除字符串前后的空白
语法格式:String tirm()
System.out.println("hello world ".trim());

19. valueOf
String中只有一个方法是静态的,不需要new对象
用法:将“非字符串”转换成“字符串”
语法格式:String.valueOf(非字符串)
调用的是底层toString方法
20. delete
语法格式:String.delete(begin x, over y)
用法: 删除从字符串 x 的索引位置开始到 y-1 的位置
六. StringBuffer
1. StringBuffer进行字符串拼接
构造一个其中不带字符的字符串缓冲区,初始容量为16个字符
可以进行大量字符串拼接操作
public class StringBufferText {
public static void main(String[] args) {
//创建一个初始化容量为16byte[] 数组(字符串缓冲区对象)
StringBuffer stringBuffer = new StringBuffer();
//拼接字符串,以后字符串统一调用append()方法
//append是追加的意思。
stringBuffer.append("a");
stringBuffer.append("b");
stringBuffer.append(3.14);
stringBuffer.append(true);
//append方法底层在进行追加的时候,如果byte数组满了,会自动扩容。
stringBuffer.append(100L);
System.out.println(stringBuffer);
}
}
2. 如何优化StringBuffer的性能
在创建StringBuffer的时候尽可能给定一个初始化容量。
最好减少底层数组的扩容次数。预估计一下,给一个大一些初始化容量。
关键点:给一个合适的初始化容量。可以提高程序的执行效率。
//指定初始化容量的StringBuffer对象(字符串缓冲区对象)
StringBuffer sb = new StringBuffer(100);
3. StringBuffer和StringBuilder的区别
StringBuffer中的方法都有: synchronized关键字修饰。表示StringBuffer在多线程环境下运行是安全的。
StringBuilder中的方法都没有: synchronized关犍字修饰,表示StringBuilder在多线程环境下运行是不安全的。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。






