java ——String , StringBuffer, StringBuilder类
一、String类概述
1.String对象一旦创建就不能改变。
2.字符串常量池。
字符串常量池的特点:池中有则直接使用,池中没有则创建新的字符串常量。
例1: “==” 比较两个对象是否引用同一实例
public class StringDemo
{
public static void main(String args[])
{
StringDemo1(); }
public static void StringDemo1()
{
String str1="abcd";
String str2="abcd";
System.out.println(str1==str2);
}
}
以上的代码运行结果为true。
原因分析:当运行到代码String str1="abcd";处,JAVA虚拟机会先检查字符串常量池中是有相同的字符串,如果有,则返回该对象的引用,否则,新创建一个字符串并返回该对象的引用。
运行到代码String str2="abcd";的时候,JAVA虚拟机发现字符串常量池中有相同的字符串,所以不再创建而是返回该对象的引用。
例2:
public class StringDemo
{
public static void main(String args[])
{
//StringDemo1();
StringDemo2(); }
public static void StringDemo2()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1==str2);
}
public static void StringDemo1()
{
String str1="abcd";
String str2="abcd";
System.out.println(str1==str2);
}
}
上述运行结果为false。
分析:运行完代码String str1="abcd";的时候,字符串常量池中将会含有一个值为abcd的字符串;执行到代码String str2=new String("abcd");时,进行了两个动作,因为使用new方法创建字符串对象的时候,所需要的构造方法中需要一个对象来创建新对象,所以,"abcd"就是一个动作,它将会在字符串常量池中寻找相同值的对象并返回该对象的引用。但是String类的构造方法中并没有直接使用该对象,而是将该对象先转换成一个字符数组,然后将该字符数组重新组装成一个字符串对象。这个过程可以通过查看源代码获得。因此使用==比较两个对象结果为false,因为它们并不是一个对象,它们的地址值不同。
例3: equals()方法 ,比较字符串对象中的字符
public class StringDemo
{
public static void main(String args[])
{
//StringDemo1();
//StringDemo2();
StringDemo3(); }
public static void StringDemo3()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1.equals(str2));
}
public static void StringDemo2()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1==str2);
}
public static void StringDemo1()
{
String str1="abcd";
String str2="abcd";
System.out.println(str1==str2);
}
}
该运行结果为true。
分析:先观察源代码
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类的equals方法复写了Object类的方法,因此它所接收的参数对象并不是String类型的,而是Object类型的,查看该源码,我们可以发现首先先比较两个对象的引用是否相同,如果相同,则返回true;这是合理的,毕竟如果两个对象的引用都相同,则两个对象一定是完全相同的。接下来,如果两个对象的引用不相同,则并不返回false,而是挨个比较两个字符串中的字符是否相同,如果比较完成之后完全相同,则返回true,否则返回false。我们最后得出结论,那就是该方法在String类中复写之后比较的是字符串内容是否相同,相同返回true,不同返回false。这里由于两个字符串内容相同,因此返回true。
例四:intern()方法。
public class StringDemo
{
public static void main(String args[])
{
//StringDemo1();
//StringDemo2();
//StringDemo3();
//StringDemo4();
//StringDemo5();
StringDemo6();
}
public static void StringDemo6()
{
String str1=new String("abcd");
String str2=str1.intern();
String str3="abcd";
System.out.println(str1==str2);
System.out.println(str2==str3);
}
public static void StringDemo5()
{
char buf[]={'A','B','C','D','E'};
String str=new String(buf);
System.out.println(str);
}
public static void StringDemo4()
{
byte buf[]={65,66,67,68,69};
String str=new String(buf);
System.out.println(str);
}
public static void StringDemo3()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1.equals(str2));
}
public static void StringDemo2()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1==str2);
}
public static void StringDemo1()
{
String str1="abcd";
String str2="abcd";
System.out.println(str1==str2);
}
}
输出结果为两行:
false
true
分析:当String对象调用intern方法时,JAVA虚拟机就会到字符串常量池中寻找字符串常量并和当前字符串内容进行比较,如果值相同,则返回该字符串常量池中的常量的引用,否则创建一个新的常量并返回该常量的引用。执行String str1=new String("abcd");的时候,字符串常量池中已经有了该常量。执行String str2=str1.intern();时,由于已经有了该常量,所以会返回该常量的引用。同理,Stirng str3="abcd";时也是如此。所以会出现这样的结果。
3.String类的构造方法。
我们经常使用String str="xxxx";的形式创建字符串对象,貌似String str=new String("xxx");的形式就没有用了,其实不然,毕竟这种方式存在即合理,很多时候使用前一种方式并不能解决问题,我们还是要使用后一种方式创建字符串,特别是在需要将其它数据类型转换成字符串类型的时候。
其它数据类型主要包括字符数组和字节数组。
3.1字节数组转换成字符串。
public class StringDemo
{
public static void main(String args[])
{
//StringDemo1();
//StringDemo2();
//StringDemo3();
StringDemo4(); }
public static void StringDemo4()
{
byte buf[]={65,66,67,68,69};
String str=new String(buf);
System.out.println(str);
}
public static void StringDemo3()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1.equals(str2));
}
public static void StringDemo2()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1==str2);
}
public static void StringDemo1()
{
String str1="abcd";
String str2="abcd";
System.out.println(str1==str2);
}
}
运行结果为:ABCDE。
3.2字符数组转换成字符串。
public class StringDemo
{
public static void main(String args[])
{
//StringDemo1();
//StringDemo2();
//StringDemo3();
//StringDemo4();
StringDemo5(); }
public static void StringDemo5()
{
char buf[]={'A','B','C','D','E'};
String str=new String(buf);
System.out.println(str);
}
public static void StringDemo4()
{
byte buf[]={65,66,67,68,69};
String str=new String(buf);
System.out.println(str);
}
public static void StringDemo3()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1.equals(str2));
}
public static void StringDemo2()
{
String str1="abcd";
String str2=new String("abcd");
System.out.println(str1==str2);
}
public static void StringDemo1()
{
String str1="abcd";
String str2="abcd";
System.out.println(str1==str2);
}
}
输出结果:ABCDE。
3.3其它构造方法。
String(byte[] bytes, int offset, int length);
该方法将指定在offset处开始处的length长度范围内的字节转换成字符串。
String(char[] value, int offset, int count);
该方法原理和上述相同。
3.4总结
通过使用String类的构造方法可以实现字节数组和字符数组向String类对象的转换。
二、String类功能
1.获取。
1.1获取字符串字符的个数,即字符串长度。
int length();
1.2根据位置获取字符
char charAt(int index);
1.3根据字符(字符串)获取在字符串中的位置
自前向后找:
int indexOf(int ch); int indexOf(int ch, int fromIndex); int indexOf(String str); int indexOf(String str, int fromIndex);
自后向前找:
int lastIndexOf(int ch); int lastIndexOf(int ch, int fromIndex); int lastIndexOf(String str); int lastIndexOf(String str, int fromIndex);
查找的时候,应当注意不要越界,否则抛出异常。
如果没有查找到,通常返回-1,可以根据此判断字符或者字符串是否存在。
1.4 获取字符串中的一部分字符串。或者称为字串。
String substring(int beginIndex, int endIndex);
使用方法:subString,返回String,有两个参数,一个是beginIndex,一个是endIndex,截取的到是endIndex之前的一个字符。即beginIndex到endIndex-1。
String substring(int beginIndex) ;
重载方法有subString ,只有一个参数,表示从指定的位置开始,一直到字符串结尾。
2.转换。
2.1将字符串变成几部分。如果有这个功能将返回字符串数组。字符串切割
String[] split(String regex, int limit);
用法举例:
String s="张三、李四、王五";
String []arr=s.split(",");
如果不是,而是.,则需要特殊处理,因为.是正则表达式中的特殊字符。转义\\.
2.2将字符串变成字符数组
Char[] toCharArray();
2.3将字符串变成字节数组
Byte[] getBytes(String charsetName);
打碎成最小单位:字节。
用法举例:
String s="ab你";
byte []arr=str.getBytes();
输出的结果却是:英文字母变成数字输出,而中文则变成了两个负数。中国的gb2312码最高位都是1,所以都是负数。
2.4字符串中的大小写转换
String toUpperCase();将字符串中的小写字符转换成大写。 String toLowerCase();将字符串中的大写字符转换成小写字符。
2.5将字符串中的内容进行替换
String replace(char oldChar, char newChar);
String replace(CharSequence target, CharSequence replacement);
CharSequence是String已经实现的接口。
2.6将字符串两端的空格去掉
String trim();
2.7 将字符串进行连接
String concat(String str);
2.8 value()方法
此方法为String类的静态方法,参数为各种基本数据类型,作用是将基本数据类型转换成字符串
3.判断
3.1两个字符串内容是否相同
boolean equals(Object anObject);
boolean equalsIgnoreCase(String anotherString)//忽略大小写进行比较,其实就是先转换成大写或者小写再进行比较。
3.2字符串中是否包含某个字符串?
boolean contains(CharSequence s);
其实是用indexOf方法也可以达到相同的目的。
3.3字符串是否以指定字符开头,是否以指定字符串结尾。
boolean endsWith(String suffix); boolean startsWith(String prefix);
4.比较方法
int compareTo(String anotherString); int compareToIgnoreCase(String str) ;
按照字典序比较两个字符串。
基本数据类型使用的是比较运算符,而对象比较使用的是compareTo方法。
三、StringBuffer类
StringBuffer类:
就是字符串缓冲区,是用于存储数据的容器。
数组也是存储数据的容器,它和StringBuffer的区别是什么?
1.长度可变
2.可以存储不同类型的数据进来。
3.最终要转成字符串才能使用。
4.可以对字符串进行修改。
该类的构造方法中的参数是整数的时候,指定了该缓冲区的初始容量大小;
该类的构造方法是字符串时,将会构造一个StringBuffer对象,并将其内容初始化为和该字符串相同。
StringBuffer类的功能:
1.添加。
append方法。参数是基本数据类型,只有两种不行:byte和short不行,但是有int可以代替。
初始容量为16个字符。
public class StringBufferDemo
{
public static void main(String args[])
{
Demo1();
}
public static void Demo1()
{
StringBuffer sb=new StringBuffer();
StringBuffer bs=sb.append(4);
System.out.println(sb==bs);
}
}
运行结果为true。
分析:一个容器加入了一些东西以后该容器仍然是该容器,并没有变化,所以结果为true。
insert方法。该方法参数分为两部分,一部分是插入的位置,一部分是插入的内容。
public class StringBufferDemo
{
public static void main(String args[])
{
//Demo1();
Demo2();
}
public static void Demo2()
{
StringBuffer sb=new StringBuffer();
sb.append("abba");
sb.insert(2,"XXXX");
System.out.println(sb);
}
public static void Demo1()
{
StringBuffer sb=new StringBuffer();
StringBuffer bs=sb.append(4);
System.out.println(sb==bs);
}
}
运行结果为:abXXXXba
2.删除。
StringBuffer delete(int start, int end);
该方法包含头不包含尾。
StringBuffer deleteCharAt(int index);
该方法删除指定位置的字符。
使用该方法可以清空缓冲区:sb.delete(0,sb.length());
3.查找。
和String类几乎相同。
4.修改。
StringBuffer replace(int start, int end, String str);
包含头不包含尾。该方法的参数个数和String相同,但是位置颠倒了。
void setCharAt(int index, char ch);
该方法比较特殊,并没有返回StringBuffer对象。该方法将指定位置上的字符替换为指定字符。
void setLength(int newLength);
在使用该方法时,如果设定的长度小于内容的长度,则会删除多余的部分。使用此方法可以达到清空StringBuffer对象的目的,但是不推荐使用。
StringBuffer reverse();
反转字符串
四、StringBuilder类
此类提供了一个与StringBuffer兼容的API。也就是功能用法一模一样。
这两个类有什么不同?
StringBuffer在jdk1.0就出现了,线程安全。
StringBuilder在jdk1.5才出现,线程不安全。
浅析StringBuffer类线程安全的原因:StringBuffer类中有append方法和delete方法,如果一个线程调用append方法,另一个线程同时调用delete方法,在不加同步锁的情况下,就会出现线程安全性问题。JDK1.0考虑的线程安全性多一点,所以加上了同步;使用同步使得线程更加安全,但是这样的好处仅仅在多线程编程中--如果是单线程,由于不会出现线程安全性问题,所以如果经常使用StringBuffer类的append方法和delete方法,就会极大的降低程序的执行效率,这是每次调用方法都必须判断锁造成的。
JDK1.5考虑到了这一点,所以将同步去掉,重新创建了一个类StringBuilder,这是考虑到程序执行效率之后的结果。
我们要知道JDK升级几乎只有三点原因:
1.简化书写
2.提高效率
3.增加安全性。
而StringBuilder类出现的目的正是为了提高效率,付出的代价就是不安全。
java ——String , StringBuffer, StringBuilder类的更多相关文章
- 重温java中的String,StringBuffer,StringBuilder类
不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...
- Java String StringBuffer StringBuilder
String 字符串常量存储在常量区,每次追加操作会创建新的对象: StringBuffer 字符串变量 线程安全 在堆上创建,每次追加操作在原对象上进行操作: 速度 StringBuffer ...
- Java之String,StringBuffer,StringBuilder类
在 java 语言中, 用来处理字符串的的类常用的有 3 个: String.StringBuffer.StringBuilder. 它们的异同点: 1) 都是 final 类, 都不允许被继承; 2 ...
- 【Java基础】String StringBuffer StringBuilder
String String是不可变的 我们都知道String不是基本数据类型,而是一个对象,并且是final类型的,不可变的.(public final class String) 查看以下代码: S ...
- 浅谈 Java 字符串(String, StringBuffer, StringBuilder)
我们先要记住三者的特征: String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全) 一.定义 查看 API 会发现,String ...
- Java String、StringBuilder和StringBuffer
转载: Java String.StringBuilder和StringBuffer 概览 在Android/Java开发中,用来处理字符串常用的类有3种: String.StringBuilder. ...
- JAVA中String和StringBuilder类的特点及使用
转自:https://www.imooc.com/code/2202 仅做个人学习记录之用,侵删! 什么是 Java 中的字符串 在 Java 中,字符串被作为 String 类型的对象处理. Str ...
- java中 String StringBuffer StringBuilder的区别
* String类是不可变类,只要对String进行修改,都会导致新的对象生成. * StringBuffer和StringBuilder都是可变类,任何对字符串的改变都不会产生新的对象. 在实际使用 ...
- Java学习笔记--String StringBuffer StringBuilder
String StringBuffer StringBuilder String http://docs.oracle.com/javase/7/docs/api/ 中文: http://www.cn ...
随机推荐
- N - 畅通工程再续 (最小生成树)
相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政 ...
- CF D. Fair(思维+DFS)
http://codeforces.com/contest/987/problem/D 题目大概: 给出一个n个城镇m条边的图,给出每个城镇拥有的特产(可能多个城镇有相同特产).有k种不同特产. 要求 ...
- TortoiseGit安装简单介绍和使用
首先,你必须有会装软件的技能和一个看得懂英语的眼睛.然后保证Git也装好了 他提供了中文版的安装包哦 安装过程尽量选择默认就行,先装上面那个啊,语言包最后装. 语言配置 因为以前装过,所以...路径是 ...
- c#工具类之Int扩展类
public static class IntHelper { /// <summary> /// 转换为2进制字符串 /// </summary> /// <param ...
- hdu1754 区间更新查询(单点更新+查询求区间最大值)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- kafka删除主题数据和删除主题
1.删除主题 在server.properties中增加设置,默认未开启 delete.topic.enable=true 删除主题命令 /bin/kafka-topics --delete --to ...
- Docker & ASP.NET Core 教程
第一篇:把代码连接到容器 第二篇:定制Docker镜像 第三篇:发布镜像 第四篇:容器间的连接 第五篇: Docker & ASP.NET Core (5):Docker Compose AS ...
- 转 windows下安装pycharm并连接Linux的python环境 以及 windows 下notepad ++编辑 linux 的文件
######sample 1:windows下安装pycharm并连接Linux的python环境 https://www.cnblogs.com/junxun/p/8287998.html wind ...
- 在Mac上配置iTerm2+Oh-My-Zsh&配置主题
本教程基本完全按照iTerm2 + Oh My Zsh 打造舒适终端体验配置 但是个人感觉博主的颜色搭配不合理,体现在补全命令的字体不清晰,提示命令与背景颜色太过相近 所以,再此之后使用了Bullet ...
- Silverlight FullScreen 全屏
<UserControl x:Class="FullScreen.MainPage" xmlns="http://schemas.microsoft.com/win ...