【数据结构 七】---字符串

时间:2023-01-04 09:03:24

String类

创建字符串

String greeting = "beijing";

编译器会使用该值创建一个 String 对象。和其它对象一样,可以使用关键字和构造方法来创建 String 对象。注意String类型是特殊的引用类型(前边有final),所以String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了如果需要对字符串做很多修改,那么应该选择使用 StringBuffer & StringBuilder 类。

String s = "Google";
System.out.println("s = " + s);

s = "Runoob";
System.out.println("s = " + s);
Google
Runoob

从结果上看是改变了,但为什么门说String对象是不可变的呢?原因在于实例中的 s 只是一个 String 对象的引用,并不是对象本身,当执行 s = “Runoob”; 创建了一个新的对象 “Runoob”,而原来的 “Google” 还存在于内存中。
【数据结构 七】---字符串

字符串长度

String 类的一个访问器方法是 length() 方法,它返回字符串对象包含的字符数。


public class StringDemo {
public static void main(String args[]) {
String site = "www.runing.com";
int len = site.length();
System.out.println( "长度 : " + len );
}
}
14

连接字符串

使用concat方法

string1.concat(string2);

使用“+”操作符

"Hello," + " runing" + "!"

常用的string方法

字符串查找

1 char charAt(int index) 返回指定索引处的 char 值。

public class Test {

public static void main(String args[]) {
String s = "www.runoob.com";
char result = s.charAt(8);
System.out.println(result);
}
}
结果为: o

字符串比较

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

按字典顺序比较两个字符串。
如果参数字符串等于此字符串,则返回值 0;
如果此字符串小于字符串参数,则返回一个小于 0 的值;
如果此字符串大于字符串参数,则返回一个大于 0 的值。

2 int compareToIgnoreCase(String str) 按字典顺序比较两个字符串,不考虑大小写。

其余常用类见菜鸟教程,感谢该教程的支持
http://www.runoob.com/java/java-string.html

StringBuffer 和 StringBuilder 类

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。


public class Test{
public static void main(String args[]){
StringBuffer sBuffer = new StringBuffer("我后边可以append字符串哦:");
sBuffer.append("www");
sBuffer.append(".runoob");
sBuffer.append(".com");
System.out.println(sBuffer);
}
}
运行结果: 我后边可以append字符串哦:www.runoob.com

【数据结构 七】---字符串

Java 中 StringBuffer 和 String 是有一定的区别的,首先,String 是被 final 修饰的,他的长度是不可变的,就算调用 String 的concat 方法,那也是把字符串拼接起来并重新创建一个对象,把拼接后的 String 的值赋给新创建的对象,而 StringBuffer 的长度是可变的,调用StringBuffer 的 append 方法,来改变 StringBuffer 的长度,并且,相比较于 StringBuffer,String 一旦发生长度变化,是非常耗费内存的!

笔试题中的字符串(错题本)

1,顺序执行下列程序语句后,则b的值是()


String a="Hello";
String b=a.substring(0,2); //He

substring 方法将返回一个包含从start到最后(不包含end )的子字符串的字符串。

length和capacity的区别

定义有StringBuffer s1=newStringBuffer(10);s1.append(“1234”)则s1.length()和s1.capacity()分别是多少?

解析:length 返回当前长度,如果字符串长度没有初始化长度大,capacity返回初始化的长度,如果append后的字符串长度超过初始化长度,capacity返回增长后的长度。

PS:如果没有明确初始化,则按默认的来
StringBuffer和StringBuilder的默认大小为16
ArrayList和LinkedList的默认大小10

StringBuffer s = new StringBuffer(x); x为初始化容量长度
s.append(“Y”); “Y”表示长度为y的字符串
length始终返回当前长度即y;
对于s.capacity():
1.当y <=x时,值为x
以下情况,容器容量需要扩展
2.当x<=y<=2*x+2时,值为 2*x+2
3.当y>=2*x+2时,值为y

String, StringBuffer,StringBuilder的区别

java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。

1.可变与不可变

String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。

private final char value[];

String 为不可变对象,一旦被创建,就不能修改它的值. . 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.

StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。

char[] value;

StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立, 如: StringBuffer sb = new StringBuffer();

不能通过赋值符号对他进行付值. , 如 sb = “welcome to here!”;//error
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法. sb.append(“hello”);

2.是否多线程安全

String中的对象是不可变的,也就可以理解为常量, 显然线程安全

AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。

StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是 线程安全的 。看如下源码:

1 public synchronized StringBuffer reverse() {

2 super .reverse();

3 return this ;

4 }

5

6 public int indexOf(String str) {

7 return indexOf(str, 0); //存在 public synchronized int indexOf(String str, int fromIndex) 方法

8 }

StringBuilder并没有对方法进行加同步锁,所以是 非线程安全的

3.StringBuilder与StringBuffer共同点

StringBuilder与StringBuffer有公共父类AbstractStringBuilder( 抽象类 )。

抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。

StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加synchronized关键字,进行同步。

最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。

效率比较String < StringBuffer < StringBuilder,但是在String S1 =“This is only a”+“simple”+“test”时,String效率最高(编译器优化的作用)。
这里详见我另一篇博客,关于编译器优化的问题
http://blog.csdn.net/sinat_33087001/article/details/74228500

null的特殊用法


public class TestClass {
private static void testMethod(){
System.out.println("testMethod");
}
public static void main(String[] args) {
((TestClass)null).testMethod();
}
}

运行正常,输出testMethod

解析: null可以被强制类型转换成任意类型(不是任意类型对象),于是可以通过它来执行静态方法。

replace和replaceAll是的区别:

1)replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence即字符串序列的意思,说白了也就是字符串);

2)replaceAll的参数是regex,即基于正则表达式的替换,比如,可以通过replaceAll(“\d”, “*”)把一个字符串所有的数字字符都换成星号;

public static void main (String[] args) { 
String classFile = "com.jd.". replaceAll(".", "/") + "MyClass.class";
System.out.println(classFile);
}

输出结果://///////MyClass.class

题目中“.”,在正则表达式中表示任何符号,所以答案是C,五个字母,2个点号,两个空格被代替。