Java面试准备之String类专项突破+源码分析

String的源码中有很多Arrays的方法使用,建议先参阅Arrays的类库

基本介绍:

  String是一个比较特殊的类,有很多种建立的方法。

  如果使用传统的构造方法比如 String s = new String("字符串");这时的对象会在堆上分配,这时候比较两个字符串地址就不相等,而用""双引号包起来的内容会在常量池中做停留,这时如果有两个内容一样的地址就一样了。

  因此,使用==来比较字符串是不靠谱的。

  String类还实现了三个接口:Serializable, CharSequence, Comparable<String>。

  serializable只是可序列化的标记,不用去管它。

  CharSequence这个接口为String提供了三个个很重要的方法:

    charAt(int index),可以返回索引的值

    length(),返回字符串序列长度

      subSequence(int start,int end),看名字就明白了,返回一个子序列

   comparable是相当重要的一个接口了(看它的子类就知道了),作用这里搬运以下JavaDOC中的原文。

    作用:此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。

    这个接口可以实现集合或者数组的排序,自然地,字符串的排序也少不了它。

    只有一个compareTo()来实现。

类库使用:

  Java中每个类的类库中的方法实在是太多了,在此不想做一个简单的罗列,我们尽量按照设计一个类的思考方式去熟悉一些方法,再配合源码的解析,应该会理解的比较清楚。

  假设,我们是Java语言的设计者(当然不是那么正规的),现在,我们已经给String这个类实现了三个接口,那么第一件事,肯定是重写这些接口了。

  把握String本质还是char型数组的原则,

    charAt(int index)方法被重写成了一个获取数组中第index个字符的方法

    length()方法就返回了数组的长度,这时候记忆两个"length"就很容易了,String调用的是一个方法所以是length(),而这个方法中又调用了数组的一个属性length

    subSequence()方法被重写成调用了subString方法,而在subString方法中进行一系列边界检查之后,调用了一个构造方法,最后调用了Arrays.copyOfRange()方法

    compareTo是最复杂的一个,它实现了两个字符串的比较。它循环比较了第一个不同的字符,并返回他们的差值,如果都相同则返回0。这个方法对外来看就是本字符串字典顺序小于被比较的字符串,返回  一个小于0的数,反之返回大于0的数;

    

 1  public int compareTo(String anotherString) {
 2         int len1 = value.length;
 3         int len2 = anotherString.value.length;
 4         int lim = Math.min(len1, len2);
 5         char v1[] = value;
 6         char v2[] = anotherString.value;
 7
 8         int k = 0;
 9         while (k < lim) {
10             char c1 = v1[k];
11             char c2 = v2[k];
12             if (c1 != c2) {
13                 return c1 - c2;
14             }
15             k++;
16         }
17         return len1 - len2;
18     }

  现在,我们实现了所有接口方法,该干一点Sting自己的事了

    首先是构造方法,在此不再赘述,但是大量的构造方法用到了Arrays.copy()这个静态方法。

    然后应该是判定了:

      是否为空:isEmpty()

      是否以特定字符串开头或结尾:startWith(),endWith()

      是否包含某字符串:contains(CharSequence s),注意参数,我们仍可以用String代替

      是否与某个字符串相等: equals(Object),源码中将Object转换为String之前,使用了instanceof判断此Object是不是String类型的,避免了抛出异常。

      是否与某个字符串相等(不考虑大小写):equalsIgnoreCase(),基本所有的不考虑大小写的用法都这么加一个后缀

    再然后应该是拆分,合并:

      替换:替换字符:replace(char old, char new)

         替换字符串:replace(CharSequence target, CharSequence replacement)

         替换所有字符串,但是第一个参数是一个正则表达式:replaceAll(String regex, String replacement)

         替换第一个字符串,但是第一个参数是一个正则表达式:replaceFirst(String regex, String replacement)

      分割:按照指定的正则表达式拆分字符串,返回值是一个字符串数组:split(String regex)

         返回一个子字符串:substring(int beginIndex, int endIndex)

         忽略前后的空白:trim()

      合并: 将指定字符串连接到此字符串的结尾:concat(String str)

      转换:将数组转换成字符串:copyValueOf(char[] data)

         将字符串转换成数组:toCharArray()

         大小写转换:toLowerCase(),toUpperCase()

         将各种类型转换成字符串:各种valueOf(Any b)

Java面试准备之String类专项突破+源码分析

时间: 2024-10-17 07:44:07

Java面试准备之String类专项突破+源码分析的相关文章

java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

我们以ByteArrayInputStream,拉开对字节类型的“输入流”的学习序幕.本章,我们会先对ByteArrayInputStream进行介绍,然后深入了解一下它的源码,最后通过示例来掌握它的用法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_02.html ByteArrayInputStream 介绍 ByteArrayInputStream 是字节数组输入流.它继承于InputStream.它包含一个内部缓冲区,该缓冲区包含从流

Java设计模式-代理模式之动态代理(附源码分析)

Java设计模式-代理模式之动态代理(附源码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的区别就是:动态代理是在运行时刻动态的创建出代理类及其对象.上篇中的静态代理是在编译的时候就确定了代理类具体类型,如果有多个类需要代理,那么就得创建多个.还有一点,如果Subject中新增了一个方法,那么对应的实现接口的类中也要相应的实习该方法,不符合设计模式原则. 动态代理的做法:在运行时刻,可以动态创建出一个实现了多个接口的代理类.每个代理类的对象都会关联一个表示内部处理

Java 序列化和反序列化(二)Serializable 源码分析 - 1

目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 Java 序列化和反序列化(二)Serializable 源码分析 - 1 在上一篇文章中讲解了一下 Serializable 的大致用法,本节重点关注 Java 序列化的实现,围绕 ObjectOutputStream#writeObject 方法展开. 1. Java 序列化接口 Java 为了方便开发人员将 Java 对象进行序列化及反序列化提供了一套方便的 API 来支持.其中包

Java 序列化和反序列化(三)Serializable 源码分析 - 2

目录 Java 序列化和反序列化(三)Serializable 源码分析 - 2 1. ObjectStreamField 1.1 数据结构 1.2 构造函数 2. ObjectStreamClass Java 序列化和反序列化(三)Serializable 源码分析 - 2 在上一篇文章中围绕 ObjectOutputStream#writeObject 讲解了一下序列化的整个流程,这中间很多地方涉及到了 ObjectStreamClass 和 ObjectStreamField 这两个类.

java io系列03之 ByteArrayOutputStream的简介,源码分析和示例(包括OutputStream)

前面学习ByteArrayInputStream,了解了“输入流”.接下来,我们学习与ByteArrayInputStream相对应的输出流,即ByteArrayOutputStream.本章,我们会先对ByteArrayOutputStream进行介绍,在了解了它的源码之后,再通过示例来掌握如何使用它. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_03.html ByteArrayOutputStream 介绍 ByteArrayOutpu

Jetty 9 Connector及Server类的一些源码分析 #1

本文的源码基于Jetty9,主要分析了Jetty 的Connector与Server类间在Jetty启动过程中的一些细节.Jetty9 对以前的Connector体系进行了重构, 结构与6和7都不同,原有的一些BIO类已经被抛弃. 先看Server 构造函数 public Server(@Name("port")int port) { this((ThreadPool)null); ServerConnector connector=new ServerConnector(this);

Java I/O系列(二)ByteArrayInputStream源码分析及理解

定义 继承了InputStream,数据源是内置的byte数组buf,那read ()方法的使命(读取一个个字节出来),在ByteArrayInputStream就是简单的通过定向的取buf元素实现的 核心源码理解 源码: 1 public ByteArrayInputStream(byte buf[], int offset, int length) { 2 this.buf = buf; 3 this.pos = offset; 4 this.count = Math.min(offset

Java BAT大型公司面试必考技能视频-1.HashMap源码分析与实现

视频通过以下四个方面介绍了HASHMAP的内容 一. 什么是HashMap Hash散列将一个任意的长度通过某种算法(Hash函数算法)转换成一个固定的值. MAP:地图 x,y 存储 总结:通过HASH出来的值,然后通过值定位到这个MAP,然后value存储到这个MAP中的HASHMAP基本原理 1. KEY 是否可以为空?可以,Null当成一个Key来存储 2. 如果Hash KEY重复了会覆盖吗?会覆盖,但返回旧的值 3. HASHMAP什么时候做扩容?put 的时候,阀值高于或等于0.7

java使用websocket,并且获取HttpSession,源码分析

一:本文使用范围 此文不仅仅局限于spring boot,普通的spring工程,甚至是servlet工程,都是一样的,只不过配置一些监听器的方法不同而已. 本文经过作者实践,确认完美运行. 二:Spring boot使用websocket 2.1:依赖包 websocket本身是servlet容器所提供的服务,所以需要在web容器中运行,像我们所使用的tomcat,当然,spring boot中已经内嵌了tomcat. websocket遵循了javaee规范,所以需要引入javaee的包 <