记录一些自己浅显的见解,还有很多不足之处
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
}
//1.构造一个空的字符串序列
public String() {
this.value = "".value;
}
//2.构造一个字符串,使之与源字符串相同,也就是创建一个传入字符串的副本
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
//3.将字符数组转成字符串
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
//4.将字符数组的一部分转成字符串
public String(char value[], int offset, int count) {
//offset是要转化的数组起始坐标,count是要转化的字符长度
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= value.length) {
this.value = "".value;
return;
}
}
//如果起始位置>字符数组长度 - 个数,则无法截取到count个字符,抛异常
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
//从offset开始,截取到offset+count位置,不包括offset+count位置
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
1.判空和判断字符串长度
//String的长度就是value数组的长度
public int length() {
return value.length;
}
//判断String是否为空,为空返回true,否则返回false
public boolean isEmpty() {
return value.length == 0;
}
2.Equals类型方法
//最常用的方法,比较两个字符串的值是否相同,重写了Object的equals方法,传参为Object类型
public boolean equals(Object anObject) {
if (this == anObject) { //如果传入的对象跟当前对象是同一对象,则返回true,因为同一对象的地址相同,地址相同,值也相同
return true;
}
if (anObject instanceof String) { //判断anObject是否是String类型,过滤掉非String类型的
String anotherString = (String)anObject; //强转为String类型
int n = value.length;
if (n == anotherString.value.length) { //比较长度是否相同,相同进入算法
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) { //循环,逐次比较每一个字符,如有不同,返回false
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
//忽略大小写的比较,为String本身的方法,传参为String类型
public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true
: (anotherString != null)
&& (anotherString.value.length == value.length)
&& regionMatches(true, 0, anotherString, 0, value.length);
}
//不常用,公有的比较方法,传入的StringBuffer对象
public boolean contentEquals(StringBuffer sb) {
return contentEquals((CharSequence)sb);
}
3.CompareTo类型方法
//常用函数,用来比较字符串大小,因为String实现了Comparable接口,所有重写了compareTo方法
//返回int类型,正数为大,负数为小,基于字符的ASSIC码比较
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; //如果遍历结束,都相同,比较两个字符串长度
}
//忽略大小写的字符串比较,
public int compareToIgnoreCase(String str) {
return CASE_INSENSITIVE_ORDER.compare(this, str);
}
//上面调用的比较器
public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
4.常用功能方法
//返回自己,默认会自动调用
public String toString() {
return this;
}
//String转Char数组并返回
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
//String 和Arrays 都属于rt.jar中的类,但是BootstrapClassloader 在加载这两个类的顺序是不同的。
//所以当String.class被加载进内存的时候,Arrays此时没有被加载,所以直接使用肯定会抛异常。而System.arrayCopy是使用native代码,则不会有这个问题。
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
//去除String首尾空格
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
//String字符大小写转化
public String toLowerCase() {
return toLowerCase(Locale.getDefault());
}
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
//是否含有CharSequence子类元素,常用于StringBuffer和StringBuilderS
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
//用于检测是否匹配给定的正则表达式,较高级,目前还没用过
public boolean matches(String regex) {
return Pattern.matches(regex, this); //实际使用的是Pattern.matches()方法
}
//String的拼接方法,用来拼接字符串
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) { //如果长度为0,说明不需要拼接
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true); //拼接的本质是创建一个新的String对象
}
5.replace,replaceAll方法
//替换方法,将older字符全部替换为newChar
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j]; //原理是创建新数组,全部复制过去
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}
//替换第一个旧字符
public String replaceFirst(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
}
//用新的字符串替换旧的字符串
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
//如果没有正则表达式限制,跟replace功能一样
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
源码太多了,下次再更新吧
public class StringInterview {
public static void main(String[] args) {
//demo1,常量池的知识点
//demo2,创建了几个对象,答案是两个
//demo3,String构造器的特点,会复制一个常量池的副本生成一个新的对象放到堆空间里
//demo4,Java中的常量优化机制
//demo5.String中变量用"+",会生成StringBuffer或StringBuilder对象,用append连接,用toString转化成String字符串,地址存放在堆空间中
}
public static void demo5() {
String s1="ab";
String s2=s1+"c";
String s3="abc";
System.out.println(s2==s3); //false,s3是存放在常量池里的,s2由于进行了字符串连接,使用了StringBuffer的toString和append方法,地址在堆中
System.out.println(s2.equals(s3)); //true
}
public static void demo4() {
String s1 = "a" + "b" + "c";
String s2 = "abc";
System.out.println(s1 == s2); //true,Java中有常量优化机制,编译时会计算成最终结果
System.out.println(s1.equals(s2)); //true
}
public static void demo1(){
String s1="abc";
String s2="abc";
System.out.println(s1==s2); //true,常量池里有的,就不会再创建新的,没有的,就创建一个放到常量池中
System.out.println(s1.equals(s2)); //true
}
public static void demo2(){
//创建了几个对象?
String str=new String("abc"); //创建了两个对象,一个是"abc"放在常量池中,一个new出来的副本放在堆空间中
}
public static void demo3(){
String s1=new String("abc");
String s2="abc";
System.out.println(s1==s2); //false,new出来的对象是放在堆空间的,"abc"对象是放在常量池里的
System.out.println(s1.equals(s2)); //true
}
}
/**
* ""是字符串常量,也是一个String对象,对象就可以调用String里的方法
* null是空常量,不能调用任何方法,否则会报空指针异常,null常量可以给任意引用类型赋值
**/
public class StringMethod {
public static void main(String[] args) {
String s6="";
String s7=null;
System.out.println(s6.isEmpty()); //true,isEmpty()是判断字符串是否为空
System.out.println(s7.isEmpty()); //NullPointerException,空指针异常
}
}
public class StringBufferTest {
public static void main(String[] args) {
String s=new String("Hi");
System.out.println(s); //Hi
change(s);
System.out.println(s); //Hi
StringBuffer sb=new StringBuffer();
sb.append("Hi");
System.out.println(sb); //Hi
change(sb);
System.out.println(sb); //HiHelloWorld
}
private static void change(StringBuffer sb) {
sb.append("HelloWorld");
}
private static void change(String s) {
s+="HelloWorld";
}
}
->int转String
public class intToString {
public static void main(String[] args){
int s=100;
System.out.println(s+""); //s+""空字符串可以int转String
int s1=1000;
System.out.println(String.valueOf(s1));//String.valueOf可以int转String
int s2=10000;
Integer i=new Integer(s2);
System.out.println(i.toString());//int转Integer转String,不推荐使用
int s3=10;
System.out.println(Integer.toString(s3));//Integer.toString()
}
}
->String转int
- String-Integer-int(Integer.intvalue()) //不推荐
- Integer.parseInt()