String系列-----String

时间:2023-03-09 14:59:39
String系列-----String

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[];
} 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<|| 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=;//从第一个字符开始比较
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=;
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, , dst, dstBegin, value.length);
}
/**
* 链接字符串,功能相当于 + 号
* 返回的是新创建的字符串
* 步骤:
* 1.定义一个新的字符数组,长度是两个字符串长度之和
* 2.把原来字符串中数据复制到新的数组中
* 3.再把要拼接的字符串加在数组后半段
* @param string
* @return
*/
public MyString concat(MyString string){
int otherLen=string.length();
if(otherLen==){
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 == && value.length > ){
char val[] = value;
for (int i = ; i <value.length ; i++) {
h= *h + val[i];
}
hash = h;
}
return h;
}
public void toMyString(){
for (int i = ; 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方法,比较的是两个字符串的值。

[ 注: == 号比较基本数据类型时,比较的是数据的值是否相同。比较引用类型的时候,比较的引用是否相同