面试:Java 字符串与数组

1. 字符串创建于存储的机制

  1. String s1 = new String("abc")String s2 = new String("abc") 这两个对象是不同的,只要是用了 new 总会生成新的对象

  2. 而对于 String s1 = “abc”String s2 = “abc”,JVM 中存在一个 字符串池,其中保存了很多 String 镀锡,并且可以被共享使用,s1s2 引用的是同一个常量池中的对象。由于 String 的实现采用了 Flyweight的设计模式,当创建一个字符串常量时,例如 String s="abc",会首先在字符串常量池中查找是否已经有相同的字符串被定义,其判断依据是 String类equals(Object obj)方法的返回值。若已经定义,则直接获取对其的引用,此时不需要创建新的对象;若没有定义,则首先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。由于 String 是不可变类,一旦创建好了就不能被修改,因此 String对象可以被共享而且不会导致程序的混乱。

问:

new String("abc") 创建了几个对象?

如果常量池中有 “abc”,只创建一个对象,如果没有,则创建两个对象。

2. “==”, equals, hashCode 有什么区别

  1. “==” 比较两个变量值内存汇总存储的值会否相等(基本类型比较值,非基本类型比较引用地址)

  2. “equals”继承自 Object,虽然 Object 中的该方法是直接使用 == 比较的,可以重写。

  3. hashCode()”也是继承自 Object,也用来鉴别两个对象是否相等,Object中的该方法返回 对象在内存中地址转换成的一个 int 值,如果没有重写该方法,任何对象的 hashCode()返回值都是不相等的。

3. String,StringBuffer,StringBuilder,StringTokenizer 区别

Java语言有4个类可以对字符或字符串进行操作,它们分别是 Character、 String、 StringBuer 和 String Tokenizer,其中 Character用于单个字符操作, String 用于字符串操作,属于不可变类,而 String Buffer 也是用于字符串操作,不同之处是 String Buffer 属于可变类

当一个字符串经常需要被修改时,最好使用 StringBuffer 来实现,如果用 String,字符串修改会创造很多无用的对象,这些对象会用垃圾回收期回收,因此会影响程序性能。

StringBulder 不像 String还能直接用字符串赋值初始化 ,只能用构造函数 StringBuffer s = new StringBuffer("Hello") 来初始化。


StringBuffer sb = new StringBuffer(s);

s.append("World");

s = s.toString();

StringBuilderStringBuffer类似,也是字符缓冲区,只不过 StringBuffer 是线程安全的,而 StringBuilder不是线程安全的,在单线程中它效率比 StringBuffer 高一点。多线程还是考虑 StringBuffer

执行效率方面:StringBuilder 最高,StringBuffer 次之,String 最低。

StringTokenizer 用来分割字符串:


import java.util.StringTokenizer;

public clas Test{

public static void main(String[] args){

StringTokenizer st = new StringTokenizer("Welcome to our country");

while(st.hasMoreTokens()){

System.out.println(st.nextToken());

}

}

}



// Welcome

// to

// our

// country

4. Java 中的数组其实也是对象

在 Java 汇总,数组不仅有自己的属性(length),也有一些方法可以被调用(例如 clone)。由于对象的特点是封装了一些数据,同时提供了一些属性和方法,从这个角度看,数组就是对象。还可以使用 instanceof关键字


instanceof int[]

5. 数组初始化方式

在 Java 中,数组被创建后会根据数组存放数据类型 初始化成对应的值( int 会初始化为 null,对象会初始化为 null ),另一个不同之处是 Java 数组在定义时,并不会给数组元素分配存储空间,因此 [] 中不需要指定数组长度,在使用时还需要分配空间:


type arrayName[];

arrayName = new type[arraySize];

初始化方法:


int[] a = new int[5]; // 默认初始化为0

int[] a = {1,2,,4,5}; // 什么鬼一个数组类型变量并初始化



int[] a;

a = new int[5];



int[] a;

a = new int[]{1,2,3,4,5};

二维数组初始化,声明时 [] 必须为空:


int[][] a = {{123},{456}}



int[][] a = new int[2][3];



// Java 中数组第二维长度可以不同

int[][] a = {{1,2}, {3,4,5}};

int[][] a = new int[2][];

a[0] = new int[]{1,2};

a[1] = new int[]{3,4,5};

6. length 属性和 length() 方法有什么区别

数组是 length 属性,Stringlength() 方法。

Java 中还有计算对象大小的方法:size(),这是针对泛型而言的,查看泛型中又多少个元素。