目录
? ? ? ? 我们这一篇来讲解String相关的概念,及其一些相关函数。
? ? ? ? 我们之前提到过,Java有8中基础数据类型,和一种引用类型String,我们已经学习过这么多知识(希望大家可以有基础),也已经知道了什么是引用数据类型。
? ? ? ? 其实在Java中,String也是类。我们进入源码观察。
????????可以发现它是被final修饰的,所以无法被继承。?
? ? ? ? 我们定义String类可以有多种方法,比如:
public static void main(String[] args) {
String name = "abc";
String str1 = new String();
String str2 = new String("ppp");
char[] arry = {'a','b','c'};
String s3 = new String(arry);
//也可以偏移
String s4 = new String(arry,0,2);//从 0 的位置上拿两个
System.out.println(s4);//ab
}
?????????我们此时调试代码:
?????????可以看到这个类中的两个成员属性,一个是value一个是hash。
????????接下来我们来观察这段代码:?
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
? ? ? ? ?因为String这个类包含了两个成员变量,第一个是val[],就是字符型数组,所以存放的是地址。
? ? ? ? 我们再来观察以下两行代码的差异:
String s1 = "";
String s2 = null;
????????因为String是引用类型对象,所以s1是空字符串;s2是空引用类型,不指向任何地址。?
? ? ? ? 不能直接比较,和C语言类似,是使用和strcmp功能类似的函数。使用equals方法进行比较。
String s1 = "hello";
String s2 = "hello";
//s1 == s2 不能直接比较,否则比较的是地址
System.out.println(s1.equals(s2));//比较内容
? ? ? ? 我们当然也可以比较大小,使用compareTo来比较大小,是不是很熟悉,这个方法是要使用接口的,所以我们进入String类内部观察,发现它确实实现了Comparable接口。?
//比较大小
System.out.println(s1.compareTo(s2));
????????返回规则:如果s1大于s2,返回正数;等于返回0;小于返回负数。
????????我们也可以忽略大小写的比较(compareToIgnoreCase),比如验证码的规则就是忽略了大小写。
//忽略大小写
System.out.println(s1.compareToIgnoreCase(s2));
? ? ? ? 获取String该下标的字符。
String s1 = "hello";
char ch = s1.charAt(1);//拿到下标值
System.out.println(ch);//e
? ? ? ? 但是如果越界会发生异常(String下标访问异常):?
? ? ? ? 获取该元素的下标。
String s1 = "hello";
int index = s1.indexOf('l');//从前到后拿到指定字符第一次出现的的下标
System.out.println(index);//2
? ? ? ? 因为有方法重载的原因,所以可以传入字符串。?
String s1 = "hello";
int index = s1.indexOf("lo");//也可以拿到字符串第一次出现的位置
System.out.println(index);//3
? ? ? ? 我们也可以从指定下标开始寻找。
String s1 = "abcabc";
int index = s1.indexOf("ab",3);//给定位置开始找 目前从下标 3 开始找
System.out.println(index);//3
? ? ? ? 从后面开始向前找。
String s1 = "abcabcabc";
int index = s1.lastIndexOf("ab",3);//给定位置开始找 目前从下标 3 开始往后找
System.out.println(index);//3
? ? ? ? 将其他类型的数据转换为String类型,因为有方法重载,所以可以对任何类型进行转换。
String s = String.valueOf(199.9);//转换为字符串
? ? ? ? 这个并不是Sting的方法,而是Integer类中的方法,可以将String转换为整形。
int data = Integer.parseInt("198");
System.out.println(data);//198
????????我们也可以将小写转变为大写。我们所有对字符串的操作,都不会改变源字符串。
String s1 = "hello";
String s2 = "HELLO";
System.out.println(s1.toUpperCase());//转大写
System.out.println(s2.toLowerCase());//转小写
?
? ? ? ? 将字符串转换为字符数组。
String s1 = "hello";
char[] array = s1.toCharArray();//转换为字符串数组
System.out.println(Arrays.toString(array));
????????格式化数组,类似于C中的printf函数。
String s = String.format("%d-%d-%d",2019,9,14);
System.out.println(s);
????????字符串替换。
String str = "abcabcabcabaabcdef";
System.out.println(str.replace("ab","99"));//替换 ab 为 999
????????我们观察该方法,发现接收类型为CharSequence。?
? ? ? ? 但是我们并没有学过这个类型,所以我们进入源码观察。?
? ? ? ? 替换第一个出现的字符或者字符串。
String ret = str.replaceFirst("ab","pp");//将第一个 ab 替换为 pp
System.out.println(ret);
????????字符串拆分。
public static void main(String[] args) {
String str = "hello abc world";
String[] ret = str.split(" ");//使用空格对其分隔
for (int i = 0; i < ret.length; i++) {
System.out.println(ret[i]);
}
System.out.println("===========");
ret = str.split(" ",2);//此时对其限制分隔次数,就分隔两次
for (int i = 0; i < ret.length; i++) {
System.out.println(ret[i]);
}
}
? ? ? ? 但是需要注意出现一些特殊的字符,比如:
String str = "192.168.10.1";
String[] ret = str.split(".");
for (int i = 0; i < ret.length; i++) {
System.out.println(ret[i]);
}
????????此时执行得不出正确结果,是因为发生了转义。此时就需要修改为\\.
String[] ret = str.split("\\.");//此时才相当于 .
?????????比如我们要在一个字符串中,同个多个符号进行分割,此时就需要用到 | 来进行连接。
String str = "name=zhangsan&age=15";
String[] ret = str.split("=|&");//要根据多个符号进行分割 需要使用 | 连接
for (int i = 0; i < ret.length; i++) {
System.out.println(ret[i]);
}
? ? ? ? 钻个牛角尖,此时如果我们要对字符串里面的 | 进行分割,就需要使用\\来防止其发挥原来作用。
String str = "name|zhangsan|age=15";
String[] ret = str.split("\\|");//要根据多个符号进行分割 需要使用 | 连接
for (int i = 0; i < ret.length; i++) {
System.out.println(ret[i]);
}
? ? ? ? 有些人就开始更钻牛角尖了,如果不用 | 连接多个分隔符该怎么办??我们也可以不使用 | 进行分隔,我们可以分别使用多次分隔。
String str = "name=zhangsan&age=15";
String[] ret = str.split("=");//要根据多个符号进行分割 需要使用 | 连接
for (int i = 0; i < ret.length; i++) {
//对其再次分割
String[] ret2 = ret[i].split("&");
for (int j = 0; j < ret2.length; j++) {
System.out.println(ret2[j]);
}
}
????????也就是说,在第一次分割的基础上,再进行一次分隔。
????????字符串截取,可以截取多个下标区间(左闭右开),也可以截取一个下标,返回的都是字符串。
String str = "abc";
String ret = str.substring(0,3);//截取 [0,3)
System.out.println(ret);//abc
ret = str.substring(2);//截取下标为 2 的元素
System.out.println(ret);//c
????????trim能去掉左边和右边的空格。
String str = " abc ";
System.out.println(str.trim());
????????找到第一个不重复的字母。
public int firstUniqChar(String s) {
//利用哈希
//之后遍历字符串找出即可
int[] count = new int[26];
for (int i = 0; i < s.length(); i++) {
count[s.charAt(i) - 'a']++;
}
for (int i = 0; i < s.length(); i++) {
if (count[s.charAt(i) - 'a'] == 1) {
return i;
}
}
return -1;
}
????????求最后一个单词长度。
public static void main1(String[] args) {
? ? ? ? Scanner in = new Scanner(System.in);
? ? ? ?
? ? ? ? // 注意 hasNext 和 hasNextLine 的区别
? ? ? ? while (in.hasNextLine()) {
? ? ? ? ? ? String str = in.nextLine();
? ? ? ? ? ? //从最后找空格
? ? ? ? ? ? int index = str.lastIndexOf(' ');
? ? ? ? ? ? String str1 = str.substring(index + 1);
? ? ? ? ? ? System.out.println(str1.length());
? ? ? ? }
? ? ? ?
? ? }
????????注意字符串是不可修改的,我们每次执行上面的操作,只要对字符串进行修改,就会产生新的字符串。