博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java基础知识系列---字符串
阅读量:5298 次
发布时间:2019-06-14

本文共 4188 字,大约阅读时间需要 13 分钟。

Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类。

String 类相关基础认知:

1、String类是final的,不可被继承。public final class String。
2、String类是的本质是字符数组char[], 并且其值不可改变。private final char value[];
然后打开String类的API文档,可以发现:
3、String类对象有个特殊的创建的方式,就是直接指定比如String x = "abc","abc"就表示一个字符串对象。而x是"abc"对象的地址,也叫做"abc"对象的引用。
4、String对象可以通过“+”串联。串联后会生成新的字符串。也可以通过concat()来串联。
5、创建字符串的方式很多,归纳起来有三类:
  其一,使用new关键字创建字符串,比如String s1 = new String("abc");
  其二,直接指定。比如String s2 = "abc";
  其三,使用串联生成新的字符串。比如String s3 = "ab" + "c";
6、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区

对象创建

字符串对象创建的原理

原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。

原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。

原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。

原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。

 

另外,String的intern()方法是一个本地方法,定义为public native String intern();

intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。

否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

 

字符串中的方法(待补充)

1.equals方法

和equals经常作为对比的是==,简单区别就是equils比较对象的值, == 用于比较引用和比较基本数据类型时具有不同的功能:

     a:比较基本数据类型,如果两个值相同,则结果为true
     b:比较引用时,如果引用指向内存中的同一对象,结果为true)

 public  boolean equals(Object obj)

public boolean equals(Object obj) {    return (this == obj);}

   其比较规则为:当参数obj引用的对象与当前对象为同一个对象时,就返回true,否则返回false.

   equals()方法的本意为确定两个对象的引用是否相同。

 注:在String中equals()方法被进行了覆盖,使其意义变为比较两个对象的内容是否一致。String中的equals是平时开发中最经常用到的,源码如下:

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;    }

 

2.hashCode方法

public
native
int
hashCode();
根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现。
作用:
对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode。在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。
为什么这么说呢?考虑一种情况,当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(注意:集合中不允许重复的元素存在)

 也许大多数人都会想到调用equals方法来逐个进行比较,这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。下面这段代码是java.util.HashMap的中put方法的具体实现:

public V put(K key, V value) {        if (key == null)            return putForNullKey(value);        int hash = hash(key.hashCode());        int i = indexFor(hash, table.length);        for (Entry
e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }

put方法是用来向HashMap中添加新的元素,从put方法的具体实现可知,会先调用hashCode方法得到该元素的hashCode值,然后查看table中是否存在该hashCode值,如果存在则调用equals方法重新确定是否存在该元素,如果存在,则更新value值,否则将新的元素添加到HashMap中。从这里可以看出,hashCode方法的存在是为了减少equals方法的调用次数,从而提高程序效率。

有人会说,可以直接根据hashcode值判断两个对象是否相等吗?肯定是不可以的,因为不同的对象可能会生成相同的hashcode值。虽然不能根据hashcode值判断两个对象是否相等,但是可以直接根据hashcode值判断两个对象不等,如果两个对象的hashcode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过equals方法。

  也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;

  如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同;

  如果两个对象的hashcode值不等,则equals方法得到的结果必定为false;

  如果两个对象的hashcode值相等,则equals方法得到的结果未知。

 

一般情况下,当我们重写equals时,一般也会去重写hashCode方法。

转载于:https://www.cnblogs.com/myadmin/p/5126950.html

你可能感兴趣的文章
在16aspx.com上下了一个简单商品房销售系统源码,怎么修改它的默认登录名和密码...
查看>>
c++回调函数
查看>>
linux下Rtree的安装
查看>>
【Java】 剑指offer(53-2) 0到n-1中缺失的数字
查看>>
Delphi中ListView类的用法
查看>>
Python Web框架Django (零)
查看>>
多米诺骨牌
查看>>
Linq 学习(1) Group & Join--网摘
查看>>
asp.net 调用前台JS调用后台,后台掉前台JS
查看>>
Attribute(特性)与AOP
查看>>
第三次作业
查看>>
苹果手表:大方向和谷歌一样,硬件分道扬镳
查看>>
Competing Consumers Pattern (竞争消费者模式)
查看>>
HDUOJ ------1398
查看>>
cf--------(div1)1A. Theatre Square
查看>>
Android面试收集录15 Android Bitmap压缩策略
查看>>
PHP魔术方法之__call与__callStatic方法
查看>>
ubuntu 安装后的配置
查看>>
VSCODE更改文件时,提示:EACCES: permission denied的解决办法(mac电脑系统)
查看>>
web前端之路,js的一些好书(摘自聂微东 )
查看>>