String字符串

char类型只能表示一个字符,而String可以表示字符串,也就是一个字符序列。但String不是基本类型,而是一个定义好的类,是一个引用类型。在Java中,可以将字符串直接量赋给String类型变量,也可以采用new String(parameter)的形式来创建字符串。

String str = "This is String”; //用字符串直接量赋值
String str = new String("Create a String through the Constructor"); //String的构造器来创建字符串

这里表示引用变量str,引用一个内容为This is String 的字符串对象。 但通常情况下,可直接称str变量是一个字符串,无须过于强调细节。

字符串特点:String类是不可变类,并且被final修饰,无法继承。 字符串对象都是不可变对象,所以对字符串进行操作时,都是返回新的字符串对象,原有字符串不会改变。

字符串在程序设计中用得非常频繁,所以掌握String字符串的常用方法是很有必要的。例如:

String普通方法

length()        //返回字符串中的字符数,即字符串长度。
charAt(int index) //根据索引位置,返回对应字符。
toLowerCase()    //把字符串中所有字母字符变成小写。
toUpperCase() //把字符串中所有字母字符变成大写。
toCharArray() //把字符串转成字符数组,即一个字符对应一个字符数组元素。
trim() //消除字符串的两边空白字符。
        String s = "ABCDEF";
System.out.println(s.length()); //
System.out.println(s.charAt(0)); //索引位置0是 A
String lowerCase = s.toLowerCase();
System.out.println(lowerCase); //abcdef
char[] ch = s.toCharArray();
System.out.println(ch[0]); // A
System.out.println(" ABC ".trim()); //ABC

 String比较方法

equals(Object anObject)           //判断当前字符串对象与指定对象是否相等。

equalsIgnoreCase(String anotherString) //判断当前字符串对象与指定String 对象是否相等,忽略大小写。

compareTo(String anotherString)        //按字典顺序比较两个字符串。

compareToIgnoreCase(String str)     //按字典顺序比较两个字符串,忽略大小写 

boolean startsWith(String prefix)    //判断是否以指定字符串作为前缀

boolean startsWith(String prefix, int toffset) //从指定的索引处开始,判断是否以指定字符串作为前缀

boolean endsWith(String suffix)     //当前字符串是否以指定字符串作为后缀。

contains(CharSequence s)         //如果包含指定字符串,则返回 true。否则false

注意:比较两个字符串内容是否相等时,很多人都会用 ==操作符来比较,但这是错的,下面说一下它们的区别。

==操作符和equals方法的区别

操作符==比较的是变量值是否相同,因为字符串是引用类型,所以操作符==只能检测两个字符串是否指向同一个引用(对象地址),但无法检测字符串对象的内容。操作符==只能用于判断基本类型以及引用类型是否为null。

要判断两个字符串变量是否相同,应该使用equals()方法来判断。两个对象指向同一引用,则说明内容相等。否则开始循环比较字符串内容。String的equals()方法实现细节:

    public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
        String s = "This is String";
String s1 = s + ""; //产生一个新字符串
System.out.println(s == s1); //两个字符串对象非同一个引用,返回false
System.out.println(s.equals(s1)); //两个字符串对象的内容相等,返回true

总结一下就是:操作符==是直接比较变量的值。若是引用类型变量,则比较引用地址是否相同。而equals()方法是比较引用对象中的内容。

演示其他比较方法

        String s = "hello world";
System.out.println(s.equalsIgnoreCase("HELLO WORLD")); //忽略大小写,比较字符串内容。true
//轮流比较字符,字符不相等时,返回字符相减结果:e - a = 4 [69- 65]
System.out.println(s.compareTo("hallo world"));
//判断前缀
System.out.println(s.startsWith("hello")); //true
//判断后缀
System.out.println(s.endsWith("worlds")); // false
//是否包含指定字符串
System.out.println(s.contains("lo wor")); //空白字符串也属于字符,别忽略了

除此之外,还有截取子字符串substring()、切割字符串split()、根据索引找字符串indexOf()、lastIndexOf()以及替换相应字符串replace()等等方法。若要了解更多方法,可查阅API。

转换字符串

有时候,我们需要将某个类型转成字符串来进行操作。例如将数值类型转成字符串,可以很快判断是几位数,可以快速判断是否是回文数。

方式有两种:采用操作符+拼接成字符串;通过静态方法valueOf(parameter)将相关类型转成对应字符串。

        String s1 = String.valueOf(123);
String s2 = 123 +"";

采用操作符+直接转成字符串是最简洁、最方便的。

字符串直接量与new String()的区别

        String s1 = "ABC";
String s2 = new String(s1); //等价于 new String("ABC");
String s3 = s1 + "";
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false

字符串直接量是一个字符串对象,而new String(s1)会构建一个同类型但不同内存空间的字符串对象。简单来说就是,两者没有指向同一个引用。所以操作符==判断为false。

s3 = s1 + ""; 这一段是运行时对字符串变量s1进行拼接,所以会产生一个新的字符串对象。所以为false。

关于对字符串直接量拼接是否相等同内容字符串

如果直接对字符串直接量进行拼接,而非采用变量形式拼接字符串,比较结果又会不同。

        String c = "C";
String s1 = "ABC";
String s2 = "AB" + c;
String s3 = "A" + "B" + "C";
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //true

因为字符串是常量,所以创建“ABC”这个字符串时,会放在常量池中。 但s2指向的字符串对象引用是到运行时才会确定, 所以会导致创建一个新字符串对象。而s3是以字符串直接量来进行拼接,这些字符串在编译时就能确定下来,编译器就在常量池查找是否存在相同的字符串。若已存在,指向同一个字符串对象,否则,另外创建字符串。

除了操作符==判断引用地址外,可以使用System.identityHashcode() 查看内存地址是否相同,identityHashcode() 是根据内存地址生成的哈希值。

可变字符串StringBuilder、StringBuffer

String是不可变类,字符串都是常量,例如“ABC”会被存储在常量池中。对字符串进行任何更改操作都会产生新的String对象。而StringBuilder与StringBuffer是可变类,它们的字符串对象可以更改,对可变字符串的操作不会生成新的对象,即对同一个字符串对象操作。

StringBuilder、StringBuffer创建字符串

        StringBuilder sb = new StringBuilder(); //空字符串
StringBuilder sb1 = new StringBuilder("字符串"); //以String对象作为参数构建字符串

StringBuilder与StringBuffer构建可变字符串对象都是通过new操作符调用构造方法,不能直接像String一样接收字符串直接量。

StringBuilder和StringBuffer的使用方式一模一样,两者只需要修改一下类名就可以无缝切换。两者的区别是StringBuilder应用于单线程环境,而StringBuffer应用于多线程环境。所以接下来只以StringBuilder作为示例。

可变字符串的常用方法(增删改查)

        append(data)        //将给定数据作为字符串追加到可变字符串尾部
insert(offset, data) //将给定数据作为字符串追加到指定的偏移位置
delete(start, end); //删除start 到 end -1 的字符
replace(start, end, str) //替换start 到 end -1 的字符
reverse();        //将该字符串进行倒置
sb.setCharAt(index, ch);; //设置 index 处的字符为给定字符
        StringBuilder sb = new StringBuilder(); //构建空的可变字符串
sb.append("String is changed");
System.out.println(sb); //原字符串对象内容被改变 String is changed
//在下标0处插入123
sb.insert(0, 123);
System.out.println(sb); //123String is changed
//删除 sb字符串的后面7位字符
sb.delete(sb.length() - 7, sb.length());
System.out.println(sb); //123String is
//替换前三位字符
sb.replace(0, 3, "!!!");
System.out.println(sb); //!!!String is
//翻转sb字符串
sb.reverse();
System.out.println(sb); // si gnirtS!!!
//设置某个下标的字符内容
sb.setCharAt(0,'A');
System.out.println(sb); //Asi gnirtS!!!

可以看到,对可变字符串作出任何更改操作,都会对其字符串对象进行操作。 相比于String,若是需要大量使用字符串的场景,建议采用可变字符串,可以节省很多内存空间。

使用可变字符串的场景

1.将数组内容转成字符串

    public static String toStringWithArray(int[] arr) {
StringBuilder sb = new StringBuilder("[");
for(int i = 0; i < arr.length; i++) {
if(i != arr.length -1) {
sb.append(arr[i] + ", ");
}else {
sb.append(arr[i] + "]");
}
}
return sb.toString();
}

如果不采用可变字符串,那么在拼接字符串过程中,会产生很多用不到的字符串对象,很浪费内存空间。

凡是需要大量拼接字符串的地方,都应该尽量使用可变字符串来完成,因为效率高,而且不占内存空间。

不可变字符串String与可变字符串StringBuilder、StringBuffer使用详解的更多相关文章

  1. new String(str.getBytes(“gbk”),“gbk”)的用法详解

    new String(str.getBytes(“gbk”),“gbk”)的用法详解 前提是str存放的是汉字 一.如果是new String(str.getBytes(“gbk”),“gbk”)时, ...

  2. JSON详解+ C# String.Format格式说明+ C# ListView用法详解 很完整

    JSON详解 C# String.Format格式说明 C# ListView用法详解 很完整

  3. LocalDate/LocalDateTime与String的互相转换示例(附DateTimeFormatter详解)

    摘自:https://www.jianshu.com/p/b7e72e585a37 LocalDate/LocalDateTime与String的互相转换示例(附DateTimeFormatter详解 ...

  4. js最实用string(字符串)类型的使用及截取与拼接详解

    var a = '世界上最远的距离不是天涯海角'; 一.通过字符获取位置或通过位置获取字符: //指定位置返回字符console.log(str.charAt(1));console.log(str[ ...

  5. java中String类、StringBuilder类和StringBuffer类详解

    本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html  版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolp ...

  6. mysql字符串函数:FIND_IN_SET()使用方法详解

    语法: FIND_IN_SET(str,strlist) 第一个参数str是要查找的字符串. 第二个参数strlist是要搜索的逗号分隔的字符串列表. 假如字符串str 在由N 子链组成的字符串列表s ...

  7. Java不可变序列String和可变序列StringBuilder、StringBuffer

    String String变量是不可变的,源码里面用了final修饰. private final char value[]; String str = "Hello"; Syst ...

  8. lua中 string.find(查找获取字符串) string.gsub(查找替换字符串) string.sub(截取字符串)

    > aaa='/p/v2/api/winapi/adapter/lgj'> print(string.find(aaa, "^/.+/adapter/(.*)"))1 ...

  9. 字符串模式匹配之KMP算法的next数组详解与C++实现

    相信来看next数组如何求解的童鞋已经对KMP算法是怎么回事有了一定的了解,这里就不再赘述,附上一个链接吧:https://www.cnblogs.com/c-cloud/p/3224788.html ...

随机推荐

  1. css中元素的auto属性值是什么意思,比如margin:0 auto表示什么?

    auto 你可以理解为一种 自动/自适应 的概念 比如 现在项目需要一个宽度为960px的整体布局居中 根据用户浏览器大小不同你将需要使用margin:0 auto;来实现. 无论用户浏览器宽度为多少 ...

  2. ioctl

    在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值. cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 ...

  3. qt 拖放dropEvent

    1.拖放操作分为两个截然不同的动作: 拖动和放下. 拖动通过 void dragEnterEvent(QDragEnterEvent * event); 来实现. 放下通过 void dropEven ...

  4. mvn install 时候报GBK编码错误解决办法

    在pom.xml里面 <properties> <!-- 文件拷贝时的编码 --> <project.build.sourceEncoding>UTF-</p ...

  5. java笔记--String类对象解析与运用

    --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3877236.html "谢谢-- 1.String中的equals和==的 ...

  6. 用Easing函数实现碰撞效果

    用Easing函数实现碰撞效果 工程中需要的源码请从这里下载: https://github.com/YouXianMing/EasingAnimation 源码: // // ViewControl ...

  7. [翻译] ASCScreenBrightnessDetector

    ASCScreenBrightnessDetector ASCScreenBrightnessDetector lets you easily detect screen brightness cha ...

  8. VSTO 开发

    http://www.cnblogs.com/yangecnu/category/499866.html http://www.cnblogs.com/brooks-dotnet/category/2 ...

  9. SQL连接的分类

    连接的分类 内连接 等值连接(INNER JOIN) 自然连接(NATURAL JOIN) 交叉连接(CROSS JOIN) 不等连接 外连接 左外连接(LEFT OUTER) 右外连接(RIGHT ...

  10. Linux 配置samba服务实现与Windows文件共享

    目录: 1.samba服务介绍 2. 安装samba服务和客户端 3.samba配置文件详解 4.配置实例 5.客户端挂载与测试 6.samba排错 1.Samba服务介绍     Samba 最先在 ...