String字符串函数

Join

如果需要把多个字符串放在一起,用一个定界符分隔,可以使用静态join方法
String str = String.join("/", "S", "M", "X", "XL");
// 输出:"S/M/X/XL"

equals

equals方法检测两个字符串是否相等,返回结果boolean类型
不区分大小写检测两个字符串是否相等,使用equalsIgnoreCase方法

注意:

一定不要使用==运算符检测两个字符串是否相等,这个运算符只能确定两个字符串是否放置在同一个位置上。
如果字符串放置在同一个位置上,它们必然相等,但是完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上。

空串与Null串

空串 "" 是长度为0的字符串,空串是一个Java对象,有自己的串长度(0)和内容(空)。
String变量还可以存放一个特殊的值,名为null,这表示目前没有任何对象与该变量关联。

检查一个字符串既不是null也不为空串,使用以下条件:

if(str != null && str.length() != 0) {}
// 注意:首先先要检查str不为null,如果一个null值上调用方法,会出现错误
public class Null {
public static void main(String[] args) {
String str = null;
if (str.length() != 0 && str != null) {
System.out.println("str为null先调用方法,报错!");
}
}
}
/*
Exception in thread "main" java.lang.NullPointerException
at string.Null.main(Null.java:11)
*/

charAt

char charAt(int index)
/*
返回给定位置的代码单元,index范围在0 -> str.length()-1之间
*/
public class CharAt {
public static void main(String[] args) {
String str = "abc";
char c = str.charAt(2);
System.out.println(c);
}
}
// 结果:c

codePointAt

int codePointAt(int index) 5.0
/*
返回给定位置开始的码点
*/
public class CodePointAt {
public static void main(String[] args) {
String str = "codePointAt";
int point = str.codePointAt(3);
System.out.println(point); // 字符'e' 对应 ascII码值 101
}
}
// 结果:101

offsetByCodePoints

int offsetByCodePoints(int startIndex, int cpCount) 5.0
/*
返回从startIndex代码点开始,位移cpCount后的码点索引
*/
public class OffsetByCodePoints {
public static void main(String[] args) {
String str = "abcdefg";
// 索引3为字符'd',位移2,此时为字符'f',其索引为5
int points = str.offsetByCodePoints(3, 2);
System.out.println(points);
}
}
// 结果:5

compareTo

int compareTo(String other)
/*
如果字符串位于other之前,返回一个负数;
如果字符串位于other之后,返回一个正数;
如果两个字符串相等,返回0
*/
public class CompareTo {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abcd";
String str3 = "abc";
String str4 = "abcdef";
String str5 = "abz";
int i = str1.compareTo(str2); // 结果:-1 返回的是字符位数的差值
int i1 = str1.compareTo(str3); // 结果:0
int i2 = str4.compareTo(str1); // 结果:3 ,str4比str1多三个字符
int i3 = str1.compareTo(str5); // 结果:-23
System.out.println(i);
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);
}
}

compareTo底层源码

public int compareTo(@NotNull String anotherString) {
int len1 = value.length; // 字符串的长度
int len2 = anotherString.value.length; // other字符串长度
int lim = Math.min(len1, len2); // 获取len1与len2的长度最小的值赋给lim
char v1[] = value; // 保存字符串中的字符
char v2[] = anotherString.value; // 保存other字符串中字符
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) { // 比较两数组中相同索引处字符的码点值
return c1 - c2; // 获取相同索引处字符的码点差值
}
k++;
}
return len1 - len2;
}

常用方法

String类与其他结构之间的转换

字节数组与字符串

@Test
public void test3() throws UnsupportedEncodingException {
String str1 = "abc123中国";
byte[] bytes = str1.getBytes();//使用默认的字符集,进行编码。
System.out.println(Arrays.toString(bytes));
byte[] gbks = str1.getBytes("gbk");//使用gbk字符集进行编码。
System.out.println(Arrays.toString(gbks));
System.out.println("******************");
String str2 = new String(bytes);//使用默认的字符集,进行解码。
System.out.println(str2);
String str3 = new String(gbks);
System.out.println(str3);//出现乱码。原因:编码集和解码集不一致!
String str4 = new String(gbks, "gbk");
System.out.println(str4);//没有出现乱码。原因:编码集和解码集一致!
}

字符数组与字符串

@Test
public void test2(){
String str1 = "abc123"; //题目: a21cb3
char[] charArray = str1.toCharArray();
for (int i = 0; i < charArray.length; i++) {
System.out.println(charArray[i]);
}
char[] arr = new char[]{'h','e','l','l','o'};
String str2 = new String(arr);
System.out.println(str2);
}

基本数据类型、包装类与字符串

@Test
public void test1(){
String str1 = "123";
// int num = (int)str1;//错误的
int num = Integer.parseInt(str1);
String str2 = String.valueOf(num);//"123"
String str3 = num + "";
System.out.println(str1 == str3);
}

StringBuffer、StringBuilder、String

对比String、StringBuffer、StringBuilder三者的效率:

从高到低排列:StringBuilder > StringBuffer > String

StringBuffer的常用方法:(与StringBuilder差不多,差在一个同步,一个不同步)

StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转
public int indexOf(String str)
public String substring(int start,int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串
public int length()
public char charAt(int n )
public void setCharAt(int n ,char ch)

String、StringBuffer、StringBuilder三者的异同?

  • String:不可变的字符序列;底层使用char[]存储 (使用final关键字修饰)
  • StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[ ]存储
  • StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储

源码分析:

String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度是16的数组。
System.out.println(sb1.length());//0 输出0原因:底层有记录append()传入实际字符的变量count,记录传入的字符个数,若是输出底层数组value.length则应该输出16实际数组长度。
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];会额外空出16个容量空间,没有被直接占用
//问题1. System.out.println(sb2.length());//3
//问题2. 扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
// 默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中。
// (int newCapacity = (oldCapacity << 1) + 2;)

开发中建议大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)
当事先知道需要大量使用append()方法添加,知道容量大小,就使用可以构造指定容量的字符串缓冲区的构造器,避免扩容(容量扩充、数组复制),提高效率。

posted @   Lz_蚂蚱  阅读(57)  评论(0编辑  收藏  举报
(评论功能已被禁用)
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起