jdk源码学习之String,手动实现一个String
package com.amazing.jdk.string_2017_12_31; import java.io.Serializable; import java.util.Arrays; /** * Created by yaming on 17-12-31. */ public final class MyString implements Serializable{ private final char value[];//数组 private int hash; private static final long serialVersionUID = -6849794470754667710L; public MyString() { this.value =new char[0]; } public MyString(char[] value) { this.value = value; } /** * 返回String长度 * @return */ public int length(){ return value.length; } /** * 取得该位置上的char * @param index * @return */ public char charAt(int index){ if(index<0|| index>=value.length) throw new StringIndexOutOfBoundsException(); return value[index]; } /** * 实现comparable接口,实现compareTo方法。 * 按词典比较String的内容,结果正,负,零。大小写不等价 * 思想: * 从第一个字符开始比较。 * 比较次数是长度小的字符串长度 * 如果前面都相同,比较字符串长度 * @param another * @return */ public int compareTo(MyString another) { int len1=value.length; char[] str1=value; int len2=another.value.length; char[] str2=another.value; int min=Math.min(len1,len2); int k=0;//从第一个字符开始比较 while (k<min){ char c1=str1[k]; char c2=str2[k]; if (c1!=c2){ /* 字符类型可以比较大小,返回值int类型 char a='a'; char b='b'; System.out.println(a-b); */ return c1-c2; } } return len1-len2; } /** * String重写了equals方法。 * 比较的是两个的值是否相同 * 步骤: * 1.用==比较是不是同一个字符串。如果是那字符串的值肯定相同 * 2.判断要比较的类型是否相同,不相同的话。肯定不同 * 3.类型相同后,判断字符串的长度是否相同.不相同肯定不同 * 4.从第一个字符开始比较,直到把原字符串比较完,只要有一个不相同,就不相同 * @return */ public boolean equals(Object object){ //如果是同一个对象,值肯定相同 if (this==object){ return true; } //判断类型是否相同 if(object instanceof MyString){ MyString str= (MyString) object; int len=value.length; //判断字符串长度是否相同 if(len==str.value.length){ char v1[]=value; char v2[]=str.value; int k=1; while (k<=len){ if(v1[k]!=v2[k]){ return false; } k++; } return true; } } return false; } /** * 从dstBegin开始,将这个字符串中的字符复制到dst中。 * @param dst * @param dstBegin */ private void getChars(char dst[], int dstBegin) { System.arraycopy(value, 0, dst, dstBegin, value.length); } /** * 链接字符串,功能相当于 + 号 * 返回的是新创建的字符串 * 步骤: * 1.定义一个新的字符数组,长度是两个字符串长度之和 * 2.把原来字符串中数据复制到新的数组中 * 3.再把要拼接的字符串加在数组后半段 * @param string * @return */ public MyString concat(MyString string){ int otherLen=string.length(); if(otherLen==0){ return this; } int len=value.length; /* 复制指定数组到新数组中 */ char[] buf= Arrays.copyOf(value,otherLen+len); /* 把string里的字符串从len位置开始放到buf里 */ string.getChars(buf,len); return new MyString(buf); } /** * 返回此字符串的hash码 * @return */ 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; } public void toMyString(){ for (int i = 0; i <value.length ; i++) { System.out.print(value[i]); } } }
分析:
1.该类被final修饰,所以不可以被继承
2.为什么每次修改字符串都new String()?
final char [] value; //String的底层是字节数组。被final修饰,该字节数组不可以被修改。所以每次修改都new一个String
3.该类重写了equals方法。
Object类里的方法是比较两个字符串的引用是否相同,String类重写了equals方法,比较的是两个字符串的值。
[ 注: == 号比较基本数据类型时,比较的是数据的值是否相同。比较引用类型的时候,比较的引用是否相同