上一节我们主要讲了String类的一些不是很常用的方法,其中需要掌握的如下,我就不再赘述了

public int length()
public boolean isEmpty()
public byte[] getBytes()
public byte[] getBytes(String charsetName)
public char charAt(int index)
public boolean equals(Object anObject)
public boolean equalsIgnoreCase(String anotherString)

  继续今天的内容

    /*
* String实现接口Comparable中的compareTo方法,通过源码我们可以看出s1.compareTo(s2)依次拿出s1和s2的第k个字符进行比较
* 如果某两个不相等,则返回这两个字符的差:c1-c2(ps:这里你需要知道java中byte、short、char在参与运算的时候将自动转换为int类型,所以最后返回的是int类型)
* 最后我们得出结论:
* 返回值是0,则两个字符串相等
*/
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value; int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
} /*
* Comparator是一个比较器,String采用成员内部类的形式定义了一个比较器,comparator和comparable一时半会也讲不清楚
* 这里你只需要知道二者都是用于比较的,comparable比较的是自然排序(其实所谓的自然排序也是程序猿规定好的),比较简单,大部分是内置的,比如说String和Integer等类都有
* 而comparator是比较一些 比较复杂的,用户自己定义的,比如说下面的不区分大小写的比较就是用comparator实现的。仔细看源代码很简单的。
*/
public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator(); private static class CaseInsensitiveComparator implements Comparator<String>, java.io.Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 8575799808933029326L; public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
c1 = Character.toLowerCase(c1);
c2 = Character.toLowerCase(c2);
if (c1 != c2) {
// No overflow because of numeric promotion
return c1 - c2;
}
}
}
}
return n1 - n2;
} //替换反序列化的对象
private Object readResolve() {
return CASE_INSENSITIVE_ORDER;
}
} /*
* String的另一个比较,也就是不区分大小写的比较,内部封装着comparator的实现类的对象
*
* 总结:String有两种比较方式
* 1.compareTo 按照自然顺序比较,区分大小写
* 2.compareToIgnoreCase 不区分大小写的比较
* 虽然二者方法名很像,但是实现原理完全不一样!!!!
*/
public int compareToIgnoreCase(String str) {
return CASE_INSENSITIVE_ORDER.compare(this, str);
} /*
* 测试两个字符串区域是否相等,还记得吗?equalsIgnoreCase方法的内部其实使用的就是regionMatches
*/
public boolean regionMatches(int toffset, String other, int ooffset, int len) {
char ta[] = value;
int to = toffset;
char pa[] = other.value;
int po = ooffset;
// Note: toffset, ooffset, or len might be near -1>>>1.
if ((ooffset < 0) || (toffset < 0) || (toffset > (long) value.length - len)
|| (ooffset > (long) other.value.length - len)) {
return false;
}
while (len-- > 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
} /*
*
*/
public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) {
char ta[] = value;
int to = toffset;
char pa[] = other.value;
int po = ooffset;
// Note: toffset, ooffset, or len might be near -1>>>1.
if ((ooffset < 0) || (toffset < 0) || (toffset > (long) value.length - len)
|| (ooffset > (long) other.value.length - len)) {
return false;
}
while (len-- > 0) {
char c1 = ta[to++];
char c2 = pa[po++];
if (c1 == c2) {
continue;
}
if (ignoreCase) { char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
continue;
} if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
continue;
}
}
return false;
}
return true;
} /*
* 从字符串开始位置toffset去匹配目标字符串prefix,很常用的方法,代码原理很简单
* startsWith(String prefix, int toffset)
* startsWith(String prefix)
* endsWith(String prefix)
*/
public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = toffset;
char pa[] = prefix.value;
int po = 0;
int pc = prefix.value.length;
// Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > value.length - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
} public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
} public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
} /*
* String重写了equals,也重写了hashCode,这里我解释一下Object中的hashCode返回的是什么,因为是原生方法,所以源代码当中并没有
* 但是自己去试试就知道是什么了,创建一个类(不重写hashCode)并实例化,输出的是一个int类型的,然后重写再输出得到的还是相同长度的int类型,
*
*/
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

java源码解析之String类(三)的更多相关文章

  1. java源码解析之String类(一)

    String是我们接触最多的类,无论是学习中还是工作中,基本每天都会和字符串打交道,从字符串本身的各种拼接.切片.变形,再到和其他基本数据类型的转换,几乎无时无刻都在使用它,今天就让我们揭开Strin ...

  2. java源码解析之String类(二)

    上一节主要介绍了String类的一些构造方法,主要分为四类 无参构造器:String(),创建一个空字符串"",区别于null字符串,""已经初始化,null并 ...

  3. java源码解析之String类(四)

    /* * 返回指定字符第一次出现的字符串内的索引 */ public int indexOf(int ch) { return indexOf(ch, 0); } /* * 返回指定字符第一次出现的字 ...

  4. java源码解析之String类(五)

    /* * 切片函数,非常重要,这里一定要牢记beginIndex是开始位置,endIndex是结束位置,区别于以前学的offset是开始位置,而count或length是个数和长度 * 比如说,new ...

  5. Java源码解析——集合框架(三)——Vector

    Vector源码解析 首先说一下Vector和ArrayList的区别: (1) Vector的所有方法都是有synchronized关键字的,即每一个方法都是同步的,所以在使用起来效率会非常低,但是 ...

  6. java源码解析之Object类

    一.Object类概述   Object类是java中类层次的根,是所有类的基类.在编译时会自动导入.Object中的方法如下: 二.方法详解   Object的方法可以分成两类,一类是被关键字fin ...

  7. TiKV 源码解析系列文章(三)Prometheus(上)

    本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...

  8. [Java源码解析] -- String类的compareTo(String otherString)方法的源码解析

    String类下的compareTo(String otherString)方法的源码解析 一. 前言 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识,  ...

  9. 【Java源码解析】Thread

    简介 线程本质上也是进程.线程机制提供了在同一程序内共享内存地址空间运行的一组线程.对于内核来讲,它就是进程,只是该进程和其他一下进程共享某些资源,比如地址空间.在Java语言里,Thread类封装了 ...

随机推荐

  1. Windows 10 子系统Linux重启(不重启Win10)

    Using CMD (Administrator) net stop LxssManager net start LxssManager

  2. HDU 1143 Tri Tiling(递归)

    意甲冠军:一些现有的1*2小盒子.求拼3*n多少个长方形的拼写. 思考: 因为它是一个递归式.肯定会遇到层的关系.仔细观察,研究发现,每层应设置2一层.(奇数层不能是矩形)而从显卡好最后一层的最后一战 ...

  3. Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听

    原文:Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听 简单记录下android 盒子开发遥控器的监听 ,希望能帮到新入门的朋友们 不多说,直接贴代码 public cla ...

  4. 利用tcpdump抓包工具监控TCP连接的三次握手和断开连接的四次挥手

    TCP传输控制协议是面向连接的可靠的传输层协议,在进行数据传输之前,需要在传输数据的两端(客户端和服务器端)创建一个连接,这个连接由一对插口地址唯一标识,即是在IP报文首部的源IP地址.目的IP地址, ...

  5. SIIA CODIE AWARDS 2017

    Business Technology Best Advertising or Campaign Management Platform Albert, Albert Choozle, Choozle ...

  6. WPF 控件的内容属性

    WPF的内容属性不应定都是content, 例如TextBlock的内容属性是Text Panel的内容属性是Children ListBox的内容属性是Items

  7. 在vs2015上使用asp.net core+ef core

    官方的文档https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html 先来看一下实现的效果

  8. 如何设置程序UAC控制

    在做项目的过程中,有很多情况会涉及到权限问题,要求必须以管理员的身份才能运行,如何强制我们的程序必须以管理员身份运行呢?在调查的过程中发现有很多方式,此处介绍一种简单的方式. 1.在VS中,右键点击工 ...

  9. mysql 在不删除数据的时,同时重新更新主键id

    1,删除原有主键: ALTER TABLE `table_name` DROP `id`; 2,添加新主键字段:ALTER TABLE `table_name` ADD `id` MEDIUMINT( ...

  10. 两种加载dll的方式

    通过链接lib文件加载dll的话,使用过程中没法动态切换 通过loadlibrary函数动态加载的话,可以动态切换