Javastring类-创新互联

Java String 类 字符串的构造:

常用的3种方式:

10年积累的网站设计、成都网站设计经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先做网站后付款的网站建设流程,更有亳州免费网站建设让你可以放心的选择与我们合作。
public class test7 {public static void main(String[] args) {String s1="qwdj1238385";//直接创建;编译器会根据值创建对象
        String s2=new String("nfihwj2393-");//通过构造方法创建
      
        char []arr={'a','s','c'};//字符数组
        String s3=new String(arr);
        System.out.println(s3);//输出asc
        //java的字符串是不会像c语言那样后面有个/0结尾

    }
}
字符串内存储存(不涉及常量池理解)

先简单认识一下String源码:
在这里插入图片描述
调试一下,可以看到确实是如此。
在这里插入图片描述
String是引用类型里边并不储存字符串,而是储的它的引用。
先简单理解一下,不介绍常量池概念;new对象的方式储存。
当我们创建String s2=s1时,他们指向同一个引用。

在这里插入图片描述

字符串的比较:

1:是否相等

引用类型的比较不能使用 = =;得使用equals方法。
数组是Object对象,如果直接使用equals方法,实质上还是使用==比较。我们的String,Arrays类都重写了equles方法。

import java.util.Arrays;

public class test7 {public static void main(String[] args) {String s1="qqq";
        String s2=new String("qqq");
        System.out.println(s1==s2);           //false
        System.out.println(s1.equals(s2));   //true
        System.out.println(s1.equalsIgnoreCase(s2));//忽略大小写比较
        int []arr1={1,2,3};
        int []arr2={1,2,3};
        System.out.println(arr1==arr2);     //false
        System.out.println(arr1.equals(arr2));  //false
        System.out.println(Arrays.equals(arr1,arr2));   //true
    }
}

2:比较大小
String已经实现Comparable接口且重写compareTo方法
所以我们直接使用就行;返回int 类型,他们的差值。是先比较第一个,如果第一个相等就继续比较第二个字符。直到比完如果相等就返回0。

public class test8 {//字符串的比较大小
    public static void main(String[] args) {String s1="abe";
        String s2=new String("abc");
        System.out.println(s1.compareTo(s2)); //2
    }
}

如果是前面都相等的情况下,那么谁的字符个数多则比较大。返回相差的字符个数字符

public class test8 {public static void main(String[] args) {String s1="abceeee";
        String s2=new String("abc");
        System.out.println(s1.compareTo(s2)); //4
        System.out.println(s1.compareToIgnoreCase(s2));//忽略大小写比较
    }
}
字符串查找

1:从前往后找

public class test9 {//查看字符串
    public static void main(String[] args) {String s1="abccdefg";
        System.out.println(s1.indexOf('p'));//在字符串查找某个字符的位置,如果没有返回-1
        System.out.println(s1.indexOf('c',3));//从下标为3开始找
    
        System.out.println(s1.indexOf("bcc"));  //查找字符串的位置
        System.out.println(s1.indexOf("bcc",3));  //从3下标开始查找字符串的位置

       
    }
}

2:从后往前找

public class test9 {//查看字符串
    public static void main(String[] args) {String s1="abccdefg";

        System.out.println(s1.lastIndexOf('c'));
        System.out.println(s1.lastIndexOf('c',5)); //从5下标开始往前找
        
        System.out.println(s1.lastIndexOf("abc"));
        System.out.println(s1.lastIndexOf("ajff",5)); //从5下标开始往前找
    }
}
转化为字符串类型
public class test10 {public static void main(String[] args) {//类名调用,static方法
        String s1=String.valueOf(123);//数字转字符
         System.out.println(s2);//123
        String s2=String.valueOf(new student(18,"str"));
        System.out.println(s2);     //这时候打印是地址,没转化成功
    }                             
}
 class student {int age=100;
 String name;

   
}

转化的前提是得重写了tostring方法。源码是如果自己没有重写toString方法它则去调用Object的。
在这里插入图片描述
重写的代码:(步骤:鼠标右键,Generate,选择toString)

@Override
    public String toString() {return "student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

重写后输出结果:
在这里插入图片描述

字符串类型转成其它类型

public class test11 {public static void main(String[] args) {int a1=Integer.parseInt("123"); //转int类型
        int a2=Integer.valueOf("123");            
        double a3=Double.parseDouble("12.3");//其它类型都是类似方法
    }
}

大小写的英文字母互相转换

public class tset12 {public static void main(String[] args) {String s="abc";
        String s1=s.toUpperCase();//小转大
        System.out.println(s);
        System.out.println(s1);
        String s3=s1.toLowerCase();//大转小
        System.out.println(s3);
    }
}

输出:
abc
ABC
abc

注意:String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了,我们并不是在原来的那一份上修改。

字符串转数组
public class test13 {public static void main(String[] args) {String s1="1ewjdh";
        String s2="djff";
        char []arr1=s1.toCharArray();
    }
}
格式化字符串(使用比较少)

推荐参考
在这里插入图片描述

字符串替换

在这里插入图片描述

public class test13 {public static void main(String[] args) {String s1 = "abcccddecdg";
        String s2 = s1.replace('c', 'd');//把所有的c换成d
        System.out.println(s2);
        String s3 = s1.replace("cd", "sb");//把所有的cd换成sb
        System.out.println(s3);
        String s4 = s1.replaceAll("cd", "sb");//也是把所有的cd换成sb,这个方法得是字符串才能用
        System.out.println(s4);
        String s5 = s1.replaceAll("c", "d");
        System.out.println(s5);
        String s6=s1.replaceFirst("cd","sb");//把第一个出现的cd换成sb,也是只能用字符串
        System.out.println(s6);
    }}

输出结果:
abdddddeddg
abccsbdesbg
abccsbdesbg
abdddddeddg
abccsbdecdg

字符串拆分

把一个完整的字符串按照指定的分隔符划分为若干个子字符串;返回的结果是字符串数组。

import java.util.Arrays;

public class test14 {public static void main(String[] args) {String s1="wnjksnaasjeda";
        String []arr=s1.split("s");
        String []arr1=s1.split("s",2);//设置只划分为两个子字符串
        System.out.println(Arrays.toString(arr));
        
        char [] a={'1','2'};
        System.out.println(a);
    }
}

在这里插入图片描述

特殊情况:需要加转义字符。

import java.util.Arrays;

public class test14 {public static void main(String[] args) {String s1="127.123.455";
        String []arr=s1.split("\\.");
        System.out.println(Arrays.toString(arr));
        
    }
}

转义字符也需要转义字符来修饰,所以就是两个\最终发挥一个作用。如果我们要使用\来划分就需要\\(| * +都得需要转义字符)

多个分隔符的情况。使用| 分隔开

import java.util.Arrays;

public class test14 {public static void main(String[] args) {String s1="127.123.4&55";
        String []arr=s1.split("\\.|&");
        System.out.println(Arrays.toString(arr));

    }
}

输出:[127, 123, 4, 55]

字符串截取
public class test12 {public static void main(String[] args) {String s1="helooworld";
        String s2=s1.substring(5);//从5位置往后截取
        System.out.println(s2);
        
        String s3=s1.substring(5,9);//截取【5-10)区间字符
        System.out.println(s3);
    }
}

输出:
world
worl

去掉字符串两边空格(空格, 换行, 制表符等)
public class test12 {public static void main(String[] args) {String s1="  hel  ooworld  ";
        String s2=s1.trim();
        System.out.println(s2);
    }
}

输出:hel ooworld

判断字符串是否包含字符串
public class test12 {public static void main(String[] args) {String s1="  hel  ooworld  ";
        System.out.println(s1.contains("h"));//true
    }
}
判断以…字符串开始
public class test12 {public static void main(String[] args) {String s1="hel  ooworld  ";
        System.out.println(s1.startsWith("hel"));//判断是否从这个字符串开始
    }
}

不得不说这个字符串类型你能想到的字符串操作,他都有实现的方法,并且这个字符串类型是非常的重要,我们在做练习的时候大部分的题不是操作数组就是操作字符串。需要用到其它方法的时候 官方文档查看

字符串内存储存(涉及常量池理解)

字符串常量池在堆里边;底层是一个StrinTable哈希表(数组与链表的组合)。
字符串到底怎么储存的?为什么会出现下面的状况????

public class test15 {public static void main(String[] args) {String s1="hello";
        String s2="hello";
        System.out.println(s1==s2);//true
        System.out.println(s1.equals(s2));//true
        String s3=new String("hello");
        System.out.println(s1==s3);//false
        System.out.println(s1.equals(s3));//true


    }
}
String s1="hello";   String s2="hello";
    我们直接使用第一种创建方式,它是先去字符串常量池看有没有这个字符串。如果有就不放进常量池,没有才添加进去。
    只要是这种双引号的"  对象"在字符串常量池存过就不会再存第二份相同的。具体看下图分析。(基于java8)

第二次创建的时候,他们的value是相同的,因为这个数组只会有一份。
值相同,String对象存的也相同。
在这里插入图片描述

new 对象的情况:创建一个新的String对象。但是它里面的value是一样的,因为这个"hello"始终只有一份。值是相同的,但是String对象是不同的。

题目1:
在这里插入图片描述

题目2:
在这里插入图片描述
题目3:
“abc”+“def"编译的时候就是相当于"abcdef”,所以4执行,6不执行。
在这里插入图片描述

intern方法

intern 是一个native方法(Native方法指:底层使用C++实现的,看不到其实现的源代码),该方法的作用是手
动将创建的String对象添加到常量池中。

public static void main(String[] args) {char[] ch = new char[]{'a', 'b', 'c'};
String s1 = new String(ch); // 将ch数组再拷贝一份,然后到String对象中,s1对象并不在常量池中,
s1.intern(); // s1.intern();调用之后,会将s1对象的引用放入到常量池中
String s2 = "abc"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
System.out.println(s1 == s2);  //输出true
}

三种创建方式内存不同的总结:

  1. String str = “hello”:在堆开辟一块内存空间,然后保存到字符串常量池,再给String引用。创建两个对象数组+String对象

  2. String str = new String(“hello”) : 会开辟两块堆内存空间,字符串"hello"保存在字符串常量池中,然后用常量池中的String对象给新开辟
    的String对象赋值。创建3个对象(常量池没有的情况)
    在这里插入图片描述

  3. String str = new String(new char[]{‘h’, ‘e’, ‘l’, ‘l’, ‘o’}) :现在堆上创建一个String对象,然后利用copyof将重新开辟数组空间,将参数字符串数组中内容拷贝到String对象中(把hello字符数组拷贝一份给String)。创建数组,数组的拷贝,String对象
    (char数组是不会直接放入常量池的,在这个构造中:this.value = Arrays.copyOf (value, value.length),是对实参变量做了拷贝,存储在堆中)

字符串的不可变

1:我们操作的字符串原来的是不会改变的,都是新建。看一下源码分析。
在这里插入图片描述

字符串的修改

不建议在String类型对象进行修改,因为每一次修改都会创建很多对象.

public class test22 {public static void main(String[] args) {String s1="hello";
       s1+="world";
    }
}     //一个简简单单拼接光String对象就创建了3给个(hello,world,helloworld)

可以看到两个代码的时间差别是非常的大
在这里插入图片描述

StringBuilder和StringBuffer

1 :StringBuilder和StringBuffer类。这两个类大部分功能是相同的
2 :String和StringBuilder大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。

public class test22 {public static void main(String[] args) {StringBuffer s=new StringBuffer("abc");
 long start=System.currentTimeMillis();
        for (int i = 0; i<100000 ; i++) { s.append(i);//追加i字符串
        }
        long end=System.currentTimeMillis();
        System.out.println(end-start);//13
    }
}

两者之间转换:
String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
StringBuilder变为String: 调用toString()方法。

String str = "abcde";
        StringBuilder str0 = new StringBuilder(str);
 

        String str = "abcde";
        StringBuilder str0 = new StringBuilder();
        str0.append(str); 
        
        str = s1.toString();

StringBuilder官方文档
String、StringBuffer、StringBuilder的区别

1: String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
2: StringBuffer与StringBuilder大部分功能是相似的
3: StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


名称栏目:Javastring类-创新互联
文章源于:http://pwwzsj.com/article/dgsgoi.html