当前位置:   article > 正文

java字符串与数组比较_Java字符串与数组

java字符串与数组比较

问题及答案来源自《Java程序员面试笔试宝典》第四章 Java基础知识 4.5字符串与数组

1、字符串创建与存储的机制是什么?

Java中字符串声明与初始化主要有两种情况:

(1)String s1 = new String("abc")与String s2 = new String("abc")语句

执行String s1 = new String("abc")语句,字符串池中不存在"abc",则会创建一个字符串常量"abc",

并将它添加到字符串常量池中,然后new String()会在堆中创建一个新的对象,s1指向堆中的String对象

紧接着创建String s2 = new String("abc")语句,因为字符串常量池中已经有了字符串常量"abc",所以

不会再创建"abc",直接new String()在堆中创建一个新的对象,然后使用s2指向这个对象

s1与s2指向堆中的不同String对象,地址自然也不相同

(2)String s1 = "abc"语句与String s2 = "abc"语句

在JVM中存在着一个字符串常量池,其中保存了着很多String 对象,s1,s2引用的是同一个常量池中的对象。

当创建一个字符串常量时,例如String s1 = "abc",会首先在字符串常量池中查找是否已经有相同的字符串被定义,

若已经定义,则直接获取对其的引用,此时不需要创建字符串常量"abc",如果没有定义,则首先创建字符串常量

"abc",然后把它加入到字符串池中,再将引用返回

例子1:

String s1 = new String("abc");   //  先查找常量区有无"abc"常量,若无则将其"abc"添加到常量区,再在堆中创建对象,将s1指向堆中的对象

String s2 = new String("abc");    //  发现在常量区已经有了"abc",在堆中创建对象,将s2指向堆中的对象

例子2:

String s1 = "abc";  //  在常量区里面创建一个"abc"字符串对象,s1获取对其的引用

String s2 = "abc";  //  发现在常量区已经有了"abc",s2直接获取对其的引用

引申 - 对于String类型的变量s,赋值语句s=null和赋值语句s=""有什么区别?

s=null,是指s不指向任何一个字符串;s=""中的s指向空字符串

笔试题 - new String("abc")创建了几个对象?

一个或两个,如果常量池中原来就有"abc",那么只创建一个对象,否则创建两个对象

2、==、equals和hashCode有什么区别?

==:是运算符,用于比较两个变量是否相等。当比较对象时,比较的是对象在内存中的地址

equals方法:用于比较两个对象是否相等,默认Object类的equals方法是比较两个对象的地址,跟==的结果一样

如果一个类没有自己定义equals方法,它默认的equals方法就是使用"=="运算符,也就是在比较两个变量指向

的对象是否是同一个对象

hashCode方法:是用来鉴定两个对象是否相等,默认Object类中的hashCode方法返回对象在内存中地址转换成

的一个int值,所以如果没有重写hashCode()方法,任何对象的hashCode()方法都是不相等的。返回一个离散的int型整数。

在集合类操作中使用,为了提高查询速度。(HashMap,HashSet等)

22a272bcb4489127e20b0f19a60e7f59.png

equals方法实际使用:

1 classPerson{2

3 }4

5 public classObjectDemo {6 public static voidmain(String[] args) {7 //Person类没有重写equals方法 而Object类中的equals方法是比较两个对象的地址

8 Person p1 = newPerson();9 Person p2 = newPerson();10 System.out.println(p1.equals(p2)); //false11

12 //String中重写了equals方法 比较的是两个字符串的内容

13 String s1 = new String("hello");14 String s2 = new String("hello");15 System.out.println(s1.equals(s2)); //true

16

17 String s3 = "hello";18 String s4 = "hello";19 System.out.println(s3.equals(s4)); //true

20 }21 }

java中的数据类型,可分为两类:

(1)基本数据类型

Java中基本数据类型有八种:byte,short,char,int,long,float,double,boolean,

他们之间的比较,用双等号(==),比较的是他们的值。

(2)复合数据类型(类)

当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new

出来的对象,他们的比较后的结果为true,否则比较后结果为false。

在Java的Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址,

但在一些类库当中这个方法被覆盖掉了,如String等,在这些类当中equals有其自身的实现,而不再是

比较对象的内存地址了

equals方法和hashCode方法的关系(用于set、map):

hashCode方法只有在set或map集合中用到

当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)

将对象放入到集合中时,首先判断要放入对象的hashCode值与集合中的任意一个元素的hashCode值是否相等,

如果不相等直接将该对象放入集合中。如果hashCode值相等,然后再通过equals方法判断要放入对象与集合中的

任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。

3733067_1319051875S4Tn.gif

3、String、StringBuffer、StringBuilder和SringTokenizer有什么区别?

Java中有5个类可以对字符或字符串进行操作,分别是Character、String、StringBuffer、StringBuilder

和SringTokenizer,其中Character用于单个字符操作,String用于字符串操作(属于不可变类),而

StringBuffer也是用于字符串操作(属于可变类)

Character的API:

boolean isDigit(char ch)        确定指定字符是否为数字。

boolean isLowerCase(char ch)  确定是否是小写字母字符

boolean isUpperCase(char ch)  确定是否大写字母字符

char toLowerCase(char ch)     将给定字符转换成大写字符

char toUpperCase(char ch)     将给定字符转换成小写字符

String的API:

1 引用类型String中的方法(4532)2 第一组: 判断方法3 boolean equals(String str);     //比较两个字符串的内容是否相等

4 boolean equalsIgnoreCase(String str); //比较两个字符串的内容是否相等(忽略大小写)

5 boolean startsWith(String subStr);   //判断某个字符串是否以指定的子串开头

6 boolean endsWith(String subStr):     //判断某个字符串是否以指定的子串结尾

7

8 第二组: 获取方法9 int length();                    //获取字符串中字符个数

10 char charAt(int index);                //谋取字符串某一个字符(指定下标)

11 String subString(int startIndex);          //从指定下标开始截取字符串,直到字符串末尾

12 String subString(int startIndex, int endIndex); //从指定下标开始截取字符串,到指定下标结束(左闭右开)

13 int indexOf(String subStr);         //获取子串第一次出现的下标

14

15 第三组: 转换方法16 String toLowerCase(); //转成小写串

17 String toUpperCase(); //转成大写串

18 Char[] toCharArray(); //变成字符数组

19

20 第四组: 其他方法21 String trim(); //去掉字符串两端的空格

22 String[] split(String str); //切割字符串

String和StringBuffer的区别:

String是不可变类,一旦对象创建其值将不能改变,而StringBuffer是可变类,对象创建后值可以改变

实例化String时可以用赋值也可以用new初始化,而实例化StringBuffer只能用new初始化

String字符串修改的原理:

当用String类型来对字符串进行修改时,其实现方法是首先创建一个StringBuffer对象,然后调用StringBuffer的

append方法,最后调用StringBuffer的toString方法把结果返回

1 String s = "Hello";2 s += " World";3 //以上代码等价于

4 StringBuffer sb = newStringBuffer(s);5 sb.append(" World");6 s = sb.toString();

StringBuilder和StringBuffer:

StringBuilder也是可以被修改的字符串,它与StringBuffer类似,都是字符串缓冲区,但是StringBuilder

不是线程安全的,如果只是在单线程中使用字符串缓冲区,那么StringBuilder的效率会更高些

而StringBuffer在必要时可以对方法进行同步,所以任意特定实例上的操作就好像是以串行顺序

发生,该顺序与所涉及的每个线程进行的方法调用顺序一致

因此在只有单线程访问时可以使用StringBuilder,当有多个线程访问时最好用线程安全的StringBuffer

StringTokenizer:

StringTokenizer是用来分割字符串的工具类,示例如下:

1 public classDemo{2 public static voidmain(String[] args) {3 StringTokenizer st = new StringTokenizer("Welcome to our country");4 while(st.hasMoreTokens()){5 System.out.println(st.nextToken());6 }7 }8 }

输出结果:

Welcome

to

our

country

总结:

在执行效率方面,StringBuilder最高,StringBuffer次之,String最低,使用如下:

如果操作的数据量比较小,应优先使用String类

如果是在单线程下操作大量数据应优先使用StringBuilder类

如果是在多线程下操作大量数据应优先使用StringBuffer类

4、Java中数组是不是对象?

数组是指具有相同类型的数据的集合,它们一般具有固定的长度,并且在内存中占据连续的空间

在C/C++中,数组名只是一个指针,这个指针指向了数组的首元素,没有属性也没有方法

而在Java中,数组不仅具有自己的属性,还有方法可以调用,故在Java中数组是对象

每个数组类型都有其对于的类型,可以通过instanceof来判断数据的类型,如下:

1 public classFindLeftAndRightBigger {2 public static voidmain(String[] args) {3 int[] a = {1, 2, 3};4 int[][] b = new int[2][3];5 String[] s = {"asfd", "saf"};6 if(a instanceof int[]){7 System.out.println("int[]");8 }9 if(b instanceof int[][]){10 System.out.println("int[][]");11 }12 if(s instanceofString[]){13 System.out.println("String[]");14 }15 }16 }17 //输出结果:18 //int[]19 //int[][]

5、Java数组的初始化方法有哪几种?

Java数组的初始化方法如下:

1 //一维数组声明:

2 type arrayName[] 或 type[] arrayName3 //二维数组声明:

4 type arrayName[][] 或 type[][] arrayName 或 type[] arrayName[]5 //数组初始化:可以在声明时直接赋值也可以在之后new6 //注:type既可以是基本数据类型也可以是类7

8 //一维数组初始化实例:

9 int[] a = new int[5]; //动态创建了一个包含5个整形值得数组,默认值为0

10 int[] a = {1, 2, 3}; //声明一个数组并初始化11

12 //二维数组初始化实例:13 //Java中二维数组的第二维长度可以不同

14 int[][] arr = {{1, 2}, {3, 4, 5}};15 int[][] arr = new int[2][];16 arr[0] = new int[]{1, 2};17 arr[1] = new int[]{3, 4, 5};

注:原生类指未被实例化的类,数组是实例化、被分配空间的类,数组不属于原生类

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

length属性:获取数组长度

length方法:计算字符串长度

1 public classtest{f2 public static void testArray(int[] arr){3 System.out.println("数组长度为" +arr.length);4 }5

6 public static voidtestString(String s){7 System.out.println("字符串长度为" +s.length());8 }9

10 public static voidmain(String[] args) {11 testArray(new int[]{1, 2, 3});   //3

12 testString("hello");          //5

13 }14 }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/730041
推荐阅读
相关标签
  

闽ICP备14008679号