java知识总结——字符串与数组

说明

  本文仅仅为了博主面试时方便查阅与梳理相关知识,如果有错误与不到位的地方,欢迎大佬指点改正,谢谢!
  阅读书籍:《java程序员面试笔试宝典》

一、字符串的创建与存储

  字符串的声明与初始化的两种情况:
  1、对于String s1 = new String(“abc”)语句和String s2 = new String(“abc”)语句,存在两个引用对象s1、s2,两个内容相同的字符串对象“abc”,它们在内存中的地址是不同的,只要用new总会生成新对象
  2、对于String s2 = "abc"语句和String s2 = "abc"语句,在JVM中存在一个字符串池,其中保存着很多String对象,并且可以被共享使用,s1、s2引用的是同一个常量池中的对象。

  String的实现采用了Flyweight的设计模式,当创建一个字符串常量时,会首先在字符串常量池中查找是否已经有相同的字符串被定义,其判断依据是String类equals(Obejct obj)方法的返回值。若已经定义,则直接获取对其的引用,此时不需要创建新的对象;若没有定义,则首先创建这个对象,然后把它加入到字符串常量池中,再将它的引用返回。

  注意:由于String是不可变类,一旦创建好了就不能修改,因此String对象可以被共享而且不会导致程序的混乱。

  对于String类型的变量s,赋值语句s = null和s = “”是否相同?
  对应赋值语句s = null,其中s是一个字符串类型的引用,它不指向任何一个字符串。而赋值语句s = ""中的是一个字符串类型的引用,它指向另一个字符串(这个字符串的值为"",即空字符串),因此,两者不相同。

  new String("abc")创建了几个对象?
  一个或两个。如果常量池中原来有“abc”,那么只创建一个对象;如果常量池中没有,那么就会创建两个对象。
  注意:堆里一定是会创建的,检查常量池中是否存在,如果存在则不创建,如果不存在则会在常量池中又创建一个。

二、“==”、equals和hashCode的区别

  1、"= ="
  “==”运算符用来比较两个变量的值是否相等。该运算符用于比较变量对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能使用“= =”运算符。
  如果两个变量是基本数据类型,可以直接使用“= =”运算符来比较其对应的值是否相等。
  如果一个变量指向的数据是对象(引用类型),对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应内存中的数值是否相等(这两个对象是否指向同一块存储空间),此时可以用“= =”运算符进行比较。但是,如果要比较这两个对象的内容是否相等,那么用“= =”运算符就无法实现了。
  2、equals
  equals是Object类提供的方法。每一个java类都继承自Object类,所以每个对象都具有equals这个方法。Object类中定义的equals(Object)方法是直接使用“= =”运算符比较的两个对象,所以在没有覆盖equals(Object)方法的情况下,equals(Object)与“= =”运算符一样,比较的是引用
  相比“= =”运算符,equals(Object)方法的特殊之处就在于它可以被覆盖,所以可以通过覆盖的方法让它不是比较引用而是比较数据内容

  如果一个类没有自己定义equals()方法,它默认的equals()方法(从Object继承)就是使用“= =”运算符,也是在比较两个变量指向的对象是否是同一对象,此时使用equals()方法和使用“= =”运算符会得到相同的结果。若比较的是两个独立的对象,则总返回false。
  如果编写的类希望能够比较该类创建的两个实例对象的内容是否相等,那么必须覆盖equals()方法,由开发人员自己来决定什么情况下两个对象的内容是相同的。

  3、hashCode
  hashCode()方法是从object类中继承过来的,它也用来鉴定两个对象是否相等。Object类中的hashCode()方法返回对象是内存中地址转换成的一个int值,所以如果没有重写hashCode()方法,任何对象的hashCode()方法都是不相等的
  虽然equals()方法也是用来判断两个对象是否相等的,但是它与hashCode()方法是由区别的。hashCode()方法返回值是int类型,equals()的返回值是boolean类型。
  一般在覆盖equals()方法的同时也要覆盖hashCode()方法,否则会导致该类无法与所有基于散列值(hash)的集合类(HashMap、HashSet、Hashtable)结合在一起正常运行。

  hashCode()方法和equals()方法的关系
  如果两个对象用equals()返回值为true,则这两个对象的hashCode()也是相等的。如果equals()返回为false(),则这两个对象的hashCode()有可能相等,有可能不相等。
  如果两个对象的hashCode()不相等,则两个对象用equals()返回值一定为false。如果两个对象的hashCode()相等,则这两个对象用equals()返回值可能为true也可能为false。

三、String、StringBuffer、StringBuilder和StringTokenizer

  java语言有4个类可以对字符或字符串进行操作,它们分别是Character、String、StringBuffer和StringTokenizer,其中,Character用于单个字符操作,String用于字符串操作,属于不可变类,而StringBuffer也是用于字符串操作,不同之处是StringBuffer属于可变类。
  String是不可变类,String对象一旦被创建,其值将不能被改变。
  StringBuffer是可变类,当对象创建后仍然可以对其值进行修改。
  由于String是不可变类,因此适合在需要被共享的场合使用,而当一个字符串经常需要被修改时,最好使用StringBuffer来实现。
  如果用String来保存一个经常被修改的字符串时,在字符串被修改时会比StringBuffer多很多附加的操作,同时生成很多无用的对象,由于这些无用的对象会被垃圾器回收,因此会影响程序的性能。
  String与StringBuffer的另外一个区别在于当实例化String时,可以利用构造函数(String s1 = new String(“world”))的方式来对其进行初始化,也可以用赋值(String s = “Hello”)的方式来初始化,而StringBuffer只能使用构造函数(StringBuffer s = new StringBuffer(“hello”))的方式来初始化。

  String字符串修改实现的原理
  当用String类型对字符串进行修改时,其实现方法是首先创建一个StringBuilder,其次调用StringBuilder的append()方法,最后调用StringBuilder的toString()方法把结果返回。

  StringBuilder也是可以被修改的字符串,它与StringBuilder类似,都是字符串缓冲区,但是StringBuilder不是线程安全的,如果只是在单线程中使用字符串缓冲区,那么StringBuilder的效率会高一些
  当有多个线程访问时,最好使用线程安全的StringBuffer。因为StringBuffer必要时可以对这些方法进行同步
  在执行效率方面,StringBuilder最高,StringBuffer次之,String最低。
  如果操作的数据量比较小,应优先使用String类;
  如果在单线程下操作大量数据,应优先使用StringBuilder类;
  如果是在多线程下操作大量数据,应优先考虑StringBuffer类。
  StringTokenizer是用来分隔字符串的工具类。

四、java中的数组是不是对象?

  概念
  数组是具有相同类型的数据的集合,它们一般具有固定的长度,并且在内存中占据连续的空间。
  在java语言中,数组不仅具有自己的属性,也有一些方法可以被调用。由于对象的特点是封装了一些数据,同时提供了一些属性和发发发,从这个角度上讲,数组是对象。
  每个数组类型都有其对应的类型,可以通过instanceof来判断数据的类型。

五、数组初始化的方式

  在java语言中,一维数组的声明方式如下

type arrayName[]或type[] arrayName

  其中,type既可以是基本的数据类型,也可以是类。
  在java语言中,数组被创建后会根据数组存放的数据类型初始化成对应的初始值。
  java数组在定义时,并不会给数组元素分配存储空间。


  完成数组的声明后,需要对其进行初始化。
  一维初始化的方式

int[] a = new int[5];//动态创建了一个包含5个整数型的数组,默认初始化为0
int[] a = {1,2,3,4,5};//声明一个数组类型变量并初始化

  在声明二维数组时,其中[]必须为空。以下是二维数组的三种声明方式:

type arrayName[][];
type[][] arrayName;
type[] arrayName[];

  二维数组的初始化方式:

type arrayName[][] = new type[行数][列数];

六、length属性和length()方法

  在java语言中,数组提供了length属性来获取数组的长度。
  length()方法是针对字符串而言的,String提供了length()方法来计算字符串的长度。

  java还提供了一个计算对象大小的方法——size()方法,该方法是针对泛型集合而言的,用于查看泛型中有多少个元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值