java源码解析之String类的compareTo(String otherString)方法

一. 前言

最近我发现了一个事情,那就是在面试笔试中,好多公司都喜欢在String字符串上出问题,涉及到方方面面的知识,包括其中的一些常用方法。

String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。

字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。

近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识, 也让我更加理解了设计者的算法思想.

我也推荐大家多读读源码, 我相信大家也会有意想不到的收获.

二. 实战

今天我分析的是String类的compareTo(String otherString)方法,

以下是我个人的分析观点, 如有哪里分析不到位的地方, 欢迎大家指出, 相互学习, 共同进步 !

首先, 尊重原作者, 先放上源码

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

下面的是我自己写的山寨compareTo()方法, 经测试, 结果与compareTo(String otherString)返回一致

说明:

1. 为避免冲突, 我定义的方法名为compares

2. 注释中已经详细地记录了分析思路, 故对代码不做过多说明

public class StringDemo {

 @Test
 public void test() {

 // 因为o的ASCII码为: 111
 // 因为a的ASCII码为: 97
 // 所以差为 : 111 - 97 = 14
 // 返回值为:14, 与compareTo返回结果一致
 System.out.println(compares("hellojava", "hellajava"));
 }

 public static int compares(String firstString, String lastString) {
  /*
  * 算法思路分析:
  * 1. 获取2个字符串, 首先把2个字符串都转化为字符数组 (为后面一个一个字符进行比较做铺垫)
  * 2. 获取2个字符串的长度, 并把最短的字符串长度作为循环的次数 (这样可以避免数组越界的异常)
  * 3. 把2个字符串从0开始遍历, 比较每一个字符, 若字符不相等时, 则返回两个字符串的差值
  * 4. 如果遍历的字符串都相等时, 则返回两个字符串的长度差
  *
  * 方法结果:
  * 1. 若两个字符串长度和字符都相等时, 则返回0
  * 2. 若两个字符长度不相等, 但大串完全包含(顺序和字符都相等)小串字符时, 则返回两个字符串的长度的差值
  *  举例:
  *  大串: helloworlds
  *  小串: helloworld
  *  因为大串完全包含小串, 所以返回长度的差值, 为1
  * 3. 若两个字符串长度和字符都不相等时, 则返回比较过程中, 某个索引位置上的字符之差
  *  举例:
  *  串1: hellojavas
  *  串2: hellajava
  *  遍历比较后, 索引4的字符不同, 所以返回两个字符的差值14, 'o' - 'a' = 14
  */

  /*
  * 1. 获取2个字符串, 首先把2个字符串都转化为字符数组 (为后面一个一个字符进行比较做铺垫)
  */
  char[] firstCh = firstString.toCharArray();
  char[] lastCh = lastString.toCharArray();

  /*
  * 2. 获取2个字符串的长度, 并把最短的字符串长度作为循环的次数 (这样可以避免数组越界的异常)
  */
  int firstLength = firstCh.length;
  int lastLength = lastCh.length;
  int lim = Math.min(firstLength, lastLength);

  // 用k记录比较的索引
  int k = 0;
  while(k < lim) {
  char c1 = firstCh[k];
  char c2 = lastCh[k];

  // 3. 把2个字符串从0开始遍历, 比较每一个字符, 若字符不相等时, 则返回两个字符串的差值
  if(c1 != c2) {
   return c1 - c2;
  }

  // 如果字符相等, 则让索引加1
  k++;
  }

  // 4. 如果遍历的字符串都相等时, 则返回两个字符串的长度差
  return firstLength - lastLength;
 }
}

三. 小结

通过源码的学习, 让我有一种知其然知其所以然的感觉, 后期会继续分享更多源码分析, 与大家共同学习 !

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Java1.8中StringJoiner的使用及源码详析

    前言 StringJoiner是Java里1.8新增的类,主要是帮助我们把一个列表拼接字符串, 或许有一部分人没有接触过. 所以本文将从使用例子入手, 分析StringJoiner的源码. 基本好的同学, 其实只要把这段例子自己运行一下, 自己看看源码就可以了.因为我觉得这个类挺简单的. 没必要看我下面的废话.... public class StringJoinerTest { public static void main(String[] args) { StringJoiner join

  • Java中byte[]、String、Hex字符串等转换的方法

    代码如下所示: /*输入一个byte和byte[]合并为byte[]*/ public byte[] byteMerger(byte byte_1, byte[] byte_2) { byte[] byte_3 = new byte[1 + byte_2.length]; byte_3[0] = byte_1; System.arraycopy(byte_2, 0, byte_3, 1, byte_2.length); return byte_3; } /*输入一个byte[]和byte[]合并

  • Java读取String分行字符串的方法

    1.场景:String字符串中带有分行,需要提取每一行出来处理. 2.参考代码如下: public static void main(String[] args) throws IOException{ String s="1\r\n2\r\n3\r\n \r\nabd\r\n"; BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(s.getBytes(Charse

  • MySQL存储表情时报错:java.sql.SQLException: Incorrect string value:‘\xF0\x9F\x92\xA9\x0D\x0A...’的解决方法

    前言 本文主要介绍了关于MySQL存储表情报错:java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\xA9\x0D\x0A...'的相关解决方法,分享出供大家参考学习,下面话不多说了,来一起看看详细的介绍: 本项目是基于Spring MVC + MySQL + Druid DataSource.在往数据库插入表情Emoji字符时报错: java.sql.SQLException: Incorrect string value:

  • Java中字符串常见题之String相关讲解

    今天给大家带来的是在面试中经常被问到的一道题: 无论在Java还是Android中,String是一个很常见的类,但是大家真的很了解吗,我这里有几个题: 1. String str1 = "abc"; String str2 = new String("abc"); 这两种创建String对象的方法有什么不同? 2. String s = "a" + "b" + "c" + "d"; 这

  • Java将Exception信息转为String字符串的方法

    一.前言 在java中,异常机制是非常有用的构成部分,异常信息对于查找错误来说是必不可少至关重要的信息,因此我们希望在发生错误的时候先看到捕捉到底异常信息.然而,通常的异常信息的输出使用e.printStackTrace(),这样异常信息会被输出到控制台中.但有的时候我们需要异常中的部分信息,需要他是一个可以处理的String类型. 二.解决方法 1.使用log4j 当我们使用log4j日志来记录运行信息时,可以直接使用下述方式: logger.error("异常信息:",e); 这样

  • java 解析由String类型拼接的XML文件方法

    首先要解析string类型的xml必须先要将其转化成dom格式,然后再进行解析取值,如下是解析代码示例: package com.company; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; /** * 解析由String类型拼接的XML格式 * @author Administrator */ p

  • java 实现将一个string保存到txt文档中

    实例如下所示: private static String savefile = "E:\\test.txt"; private static void saveAsFileWriter(String content) { FileWriter fwriter = null; try { fwriter = new FileWriter(savefile); fwriter.write(content); } catch (IOException ex) { ex.printStack

  • java判断String类型是否能转换为int的方法

    使用正则表达式,效率较高 public boolean canParseInt(String str){ if(str == null){ //验证是否为空 return false; } return str.matches("\\d+"); //使用正则表达式判断该字符串是否为数字,第一个\是转义符,\d+表示匹配1个或 //多个连续数字,"+"和"*"类似,"*"表示0个或多个 } 以上这篇java判断String类型是

  • java读取文件内容为string字符串的方法

    直接就把项目中的方法贴出来吧 /** * 读出城市列表文件 */ private String readCityFile() { File file02 = new File(path_xinfu, "/cityList.json"); FileInputStream is = null; StringBuilder stringBuilder = null; try { if (file02.length() != 0) { /** * 文件有内容才去读文件 */ is = new

随机推荐