文章目录
Sting概要
String 类,对于计算机来说,绝大部分数据处理其实分为两大类,一个是纯数字处理,一类就是对字符串的处理。而实际问题中大部分都是对字符串进行处理。其实很好理解日常对话都是以字符串来进行回传。比如我说:“你好”,你回我:“大家好”。我们就需要将这些数据进行处理,如存储,拆分,拼接等等。
String的基础实现逻辑
学习计算机编程,相信大家都听过一句话,C生万物。这里的万物指的是编程语言。包括c++,java,python,或者其他语言,他们都需要c语言作为底层语言。而java对于字符串有一个专门的基本类型—String,然而在C语言中是不存在字符串类型的,也就是大家会发现8大基本类型是么有字符串类型的。C语言的字符串表达,是通过字符数组进行表示。所以,在java底层中也是通过字符数组来表达的,然后将它封装在了String类中。所以就此演变出了,三种字符串构建方式。
第一种:通过常量串构造
(常量,在我的另一篇文章中有详细介绍:final中有介绍):(https://blog.csdn.net/Cheer_RIO/article/details/130590251)
public static void main(String[]args){
String str="hello";
System.out.println(str);
}
第二种:实例化对象构建
(实例化对象,在我的另一篇文章中有详细介绍:构造方法中有介绍)
public static void main(String[]args){
String str=new String("hello");
System.out.println(str);
}
第三种:通过字符数组构建
public static void main(String[]args){
char[]array={'h','e','l','l','o'};
String s3=new String(array);
System.out.println(s1);
}
String str=new String("hello");
String str1=new String("world");
String str2=str;
所以可以知道String它是引用类型。所以在内存中的存储方式,HashMap 的方式。
String对象的比较
字符串的比较是非常常见的操作,字符串排序,字符串对应。而java中提供了4种方式。
第一种:‘==’ 比较
String不是8种类型中的一种,所以= =号比较是无法直接比较数值的,‘= =’来判断引用类型,就是在判断是否引用同一个对象。
String s1="hello";
String s2="hello";
String s3=s1;
System.out.println(s1==s2); //false
System.out.println(s1==s3); //true
int a=10;
int b=20;
int c=10;
System.out.println(a==b); //false
System.out.println(a==c); //true
第二种:调用父类object中的equals方法进行比较(按字典顺序:字典顺序就是字符的大小顺序)
equals返回的类型是boolean类型
String s1="hello";
String s2="hello";
String s3=s1;
System.out.println(s1.equals(s2)); //true
System.out.println(s1.equals(s3)); //true
第三种:通过构造器compareTo进行比较(按照字典序进行比较)
比较规则:
- 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
- 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值
Strings1=newString("abc");
Strings2=newString("ac");
Strings3=newString("abc");
Strings4=newString("abcde");
System.out.println(s1.compareTo(s2)); //不同长度,输出-1
System.out.println(s1.compareTo(s3)); //相同长度,输出0
System.out.println(s1.compareTo(s4)); //前k个字符完全相同,输出长度差值-2
第四种:compareToIgnoreCase方法比较:与compareTo相似,但是忽略大小写
Strings1=newString("abc");
Strings2=newString("ac");
Strings3=newString("ABc");
Strings4=newString("abcAB");
System.out.println(s1.compareTo(s2)); //不同长度,输出-1
System.out.println(s1.compareTo(s3)); //相同长度,输出0
System.out.println(s1.compareTo(s4)); //前k个字符完全相同,输出长度差值-2
查找字符,和相关字符所在位置。
查找字符是一个使用非常频繁的操作。对于现在来说,每天会有大量数据,大部分都是以字符串的形式出现,而绝大部分对于我们来说是不用的。所以如何精确找到我们要的数据就及其重要。
方法 | 功能 | 频率 |
---|---|---|
char charAt(int index) | 返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常 | 常用 |
int indexOf(int ch) | 返回目标字符第一次出现的位置,没有返回-1 | 一般 |
int indexOf(int ch, int fromIndex) | 从fromIndex位置开始找ch第一次出现的位置,没有返回-1 | 一般 |
int indexOf(String str) | 返回str第一次出现的位置,没有返回-1 | 一般 |
int indexOf(String str, int fromIndex) | 从fromIndex位置开始找str第一次出现的位置,没有返回-1 | 一般 |
int lastIndexOf(int ch) | 从后往前找,返回ch第一次出现的位置,没有返回-1 | 一般 |
int lastIndexOf(int ch, int fromIndex) | 从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1 | 一般 |
int lastIndexOf(String str) | 从后往前找,返回str第一次出现的位置,没有返回-1 | 一般 |
int lastIndexOf(String str, int fromIndex) | 从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1 | 一般 |
数据之间的转换。
第一种:数值与字符串之间的转换
String类中在应对这样的情况,为我们提供了valueOf方法,其中包括,数字转换,字符转换
String s1 = String.valueOf(1234);
String s2 = String.valueOf(12.34);
第二种:字符串中大小写之间的转换
为了应对字符串转换的常见问题,String类中提供了两种方法:toUpperCase(转换为大写)、toLowerCase(转换为小写)
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO";
// 小写转大写
System.out.println(s1.toUpperCase());
// 大写转小写
System.out.println(s2.toLowerCase());
}
第三种:字符串转字符数组
String类中提供了toCharArray方法,将字符串直接转换为字符数组。
public static void main(String[] args) {
String s = "hello";
// 字符串转数组
char[] ch = s.toCharArray();
// 数组转字符串
String s2 = new String(ch);
System.out.println(s2);
}
第四种(拓展):字符转换为数字
在java中字符是无法将字符直接转换为数字的。数字只提供了,字符串转换为数字,而String 提供了字符转换为数字.
int num=Integer.parseInt(String.valueOf('4'));
字符串替换
使用一个指定的新的字符串替换掉已有的字符串数据,( 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.后面会解释)
返回类型 | 方法 | 功能 |
---|---|---|
String | replaceAll(String regex, String replacement) | 替换所有的指定内容 |
String | replaceFirst(String regex, String replacement) | 替换首个内容 |
字符串拆分
可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串
返回类型 | 方法 | 功能 |
---|---|---|
String[] | split(String regex) | 将字符串全部拆分 |
String[] | split(String regex, int limit) | 将字符串以指定的格式,拆分为limit组 |
这里有个小细节,以什么字符串拆分的,那个字符串就会在原字符中小消失,并不会出现在字符串数组中
String str = "world hello" ;
String[] result = str.split(" ") ; // 按照空格拆分
for(String s: result) {
System.out.println(s);
}
注意事项:
- 字符"|“,”*“,”+"都得加上转义字符,前面加上 “\” .
- 而如果是 “” ,那么就得写成 “\\” .
- 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
字符串截取
从一个完整的字符串之中截取出部分内容
返回类型 | 方法 | 功能 |
---|---|---|
String | substring(int beginIndex) | 从指定索引截取到结尾 |
String | substring(int beginIndex, int endIndex) | 截取部分内容 |
String str = "helloworld" ;
System.out.println(str.substring(5));
System.out.println(str.substring(0, 5));
//
注意事项:
- 索引从0开始
- 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标
字符串的不可变性
String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改。原因在于在String设计之初,就是无法改变。
所以我们每一次对于,原来的String类型的字符串进行修改都会产生一个新的引用。也就是说,对String类型的频繁修改,就在不断实例化对象。不断销毁,不断创建的过程。所以就特别慢。
为什么 String 要设计成不可变的?(不可变对象的好处是什么?)
- 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
- 不可变对象是线程安全的.
- 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.
所以java给出了另外两种可选的方式。
第一种:StringBuffer
返回类型 | 方法 | 功能 |
---|---|---|
StringBuffer | append(Stringstr) | 在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、double、float、int、long、Object、String、StringBuff的变量 |
char | charAt(int index) | 获取index位置的字符 |
int | length() | 获取字符串的长度 |
int | capacity() | 获取底层保存字符串空间总的大小 |
void | ensureCapacity(int mininmumCapacity) | 扩容 |
void | setCharAt(int index,char ch) | 将index位置的字符设置为ch |
int | indexOf(String str) | 返回str第一次出现的位置 |
int | indexOf(String str, int fromIndex) | 从fromIndex位置开始查找str第一次出现的位置 |
int | lastIndexOf(String str) | 返回最后一次出现str的位置 |
int | lastIndexOf(String str,int fromIndex) | 从fromIndex位置开始找str最后一次出现的位置 |
StringBuffer | insert(int offset, String str) | 在offset位置插入:八种基类类型 & String类型 & Object类型数据 |
StringBuffer | deleteCharAt(int index) | 删除index位置字符 |
StringBuffer | delete(int start, int end) | 删除[start, end)区间内的字符 |
StringBuffer | replace(int start, int end, String str) | 将[start, end)位置的字符替换为str |
String | substring(int start) | 从start开始一直到末尾的字符以String的方式返回 |
String | substring(int start,int end) | 将[start, end)范围内的字符以String的方式返回 |
StringBuffer | reverse() | 反转字符串 |
String | toString() | 将所有字符按照String的方式返回 |
注意:
String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:
- String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
- StringBuilder变为String: 调用toString()方法。
第二种:StringBuilder(方法与StringBuffer相似,但是有些方法没有)
具体可以看:链接
小结
String、StringBuffer、StringBuilder的区别
- String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
- StringBuffer与StringBuilder大部分功能是相似的
- StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操 作
其他文章接口
1.String方法(重要,对于操作字符串有巨大的帮助)
2.java常用的接口及其方法(包含拷贝,比较,排序,构造器)
3.初阶数据结构
3.1 顺序表:ArrayList
3.2 链表:LinkedList
3.3 栈:Stack
3.4 队列:Queue
3.5 二叉树:Tree
3.6 优先级队列:PriorityQueue(堆排序)
3.7 Map和Set
HashMap和HashSet,TreeMap和TreeSet
文章链接
4. 排序(7种方式)
4.1 插入排序(两种)
4.2 选择排序(两种)
4.3 快速排序
4.4 堆排序
里面有堆排序的实现和逻辑
文章链接