Java 字符串

Java中为字符串提供的常量池,以及由常量池带来的字符串操作特性

1、Java语言使用Unicode字符集,默认使用UTF-8格式;因此Java的字符串也使用UTF-8编码;

  UTF-8是一种针对Unicode的可变长度字符编码,用1到4个字节编码Unicode字符;

  Java语言中的字符串实际上是使用字符型数组char[]存储;

复制代码
public class Test1 {
    public static void main(String[] args) {
        String str1 = "abc";
        System.out.println(str1);
        char[] chs = {'a', 'b', 'c'};
        String str2 = new String(chs);
        System.out.println(str2);
    }
}
/**
 * abc
 * abc
 */
复制代码

2、字符串可以用两种方式赋值,且有一个非常重要的特征,即不可变性(immutable);

  不可变的意思是:一旦一个字符串被创建后,它的值就不能被修改;

String s1 = "hello";
s1 = "world";

•上述代码的执行过程如下:

  并不是把Hello改为了World,而是重新分配空间存储World;

  s1的值发生了改变,指向了新的空间;

3、为了能够重用这些不变的字符串,Java使用了字符串常量池;

  凡是用=直接赋值的方式得到的字符串,都存储在常量池中;相同的共用一个具体字符串;

  使用new创建的字符串不适用常量池,每次都分配新的内存空间;

String s2 = "hello";
String s3 = "hello";
String s4 = new String("hello");
String s5 = new String("hello");

  s1与s2使用=赋值,所以使用到常量池,指向同一个Hello;

  s3与s4使用new创建,没有用常量池,每次都分配新的空间,指向一个新的Hello;

  

4、•用下列代码验证上页结论:

复制代码
public class Test2 {
    public static void main(String[] args) {
        String s2 = "hello";
        String s3 = "hello";
        String s4 = new String("hello");
        String s5 = new String("hello");
        //双引号括起来的字符串用等号赋值,字符串存放到常量池中
        //new String 存储到堆空间
        System.out.println("s2 == s3:" + (s2 == s3));   //true
        System.out.println("s4 == s5:" + (s4 == s5));   //false
        System.out.println("s2 == s4:" + (s2 == s4));   //false
    }
}
复制代码

字符串的常用方法的使用

1、子串截取相关方法

复制代码
public class StringTest1 {
    public static void main(String[] args) {
        String str = "hello";
        System.out.println(str.substring(2));
        //substring startIndex 到 endIndex  [1,4)  左闭右开
        System.out.println(str.substring(1, 4));
    }
}
/**
 * llo
 * ell
 */
复制代码

2、String类中定义了一系列字符串相关方法

方法声明方法描述
int indexOf(int ch) 返回字符串中字符ch第一次出现的位置索引值
int indexOf(int ch, int fromIndex) 返回从 fromIndex位置往从左往右查找,第一次搜索到ch的索引位置
int indexOf(String str) 返回字符串中子串str第一次出现的位置索引值
int indexOf(String str, int fromIndex) 返回从 fromIndex位置往从左往右查找,第一次搜索到子串str的索引位置
int lastIndexOf(int ch) 返回字符串中字符ch最后一次出现的位置索引值
int lastIndexOf(int ch, int fromIndex) 返回从 fromIndex位置往从右往左查找,第一次搜索到ch的索引位置
int lastIndexOf(String str) 返回字符串中子串str最后一次出现的位置索引值
int lastIndexOf(String str, int fromIndex): 返回从 fromIndex位置往从右往左查找,第一次搜索到str的索引位置
char charAt(int index) 返回指定索引位置的字符
复制代码
public class StringTest1 {
    public static void main(String[] args) {
        String str = "seventeen";
        System.out.println(str.indexOf('t'));//5
        System.out.println(str.indexOf('v', 2));//2
        System.out.println(str.indexOf("ee"));//6
        System.out.println(str.indexOf("eve", 1));//1
        System.out.println(str.lastIndexOf('e'));//7
        System.out.println(str.lastIndexOf('e', 6));//6
        System.out.println(str.lastIndexOf("ee"));//6
        System.out.println(str.charAt(6));//e
    }
}
复制代码

3、

方法声明方法描述
static String valueOf(boolean b) 将布尔类型参数以字符串类型返回
static String valueOf(char c) 将字符类型参数以字符串类型返回
static String valueOf(char[] data) 将字符数组类型参数以字符串类型返回
static String valueOf(char[] data, int offset, int count) 将字符数组类型参数的一部分以字符串类型返回
static String valueOf(double d) 将double类型参数以字符串类型返回
static String valueOf(float f) 将float类型参数以字符串类型返回
static String valueOf(int i) 将int类型参数以字符串类型返回
static String valueOf(long l) 将long类型参数以字符串类型返回
static String valueOf(Object obj) 将引用类型参数以字符串类型返回,实际调用toString方法

 

复制代码
public class Seventeen {
    private String name;
    private int age;
    public Seventeen(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Seventeen{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
复制代码
复制代码
public class TestString2 {
    public static void main(String[] args) {
        int i = 10;
        System.out.println(String.valueOf(i));
        char[] chs = {'a', 'b', '1', '#', '9'};
        System.out.println(String.valueOf(chs, 1, 3));
        //把对象转换成String,调用对象的toString方法,如果没有重写就会取父类找,直至到Object的toString
        Seventeen carat = new Seventeen("Jun", 25);
        System.out.println(String.valueOf(carat));
    }
}
/**
 * 10
 * b1#
 * Seventeen{name='Jun', age=25}
 */
复制代码

4、

方法声明方法描述
int compareTo(String anotherString) 比较两个字符串的字典顺序,返回值为正数,表示大于 如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。 如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。
boolean endsWith(String suffix) 判断一个字符串是否以suffix结尾
byte[] getBytes() 将字符串转换为byte数组
byte[] getBytes(Charset charset) 将字符串用指定的编码格式转换为byte数组
int length() 返回字符串的长度
boolean startsWith(String prefix) 判断字符串是否以prefix开头
boolean startsWith(String prefix, int toffset) 判断字符串中从toffset个字符开始后的子串中,是否以prefix开头
String trim() 将字符串的首尾空格去掉
复制代码
public class TestString3 {
    public static void main(String[] args) {
        String str1 = "helloworld";
        String str2 = "hbcdefghi";
        int compareResult = str1.compareTo(str2);
        System.out.println(compareResult);
        //判断字符串是否以xxx开头
        System.out.println(str1.startsWith("hell"));
        //判断字符串是否以xxx结尾
        System.out.println(str2.endsWith("hbi"));
        //获取String的byte数组
        byte[] bytes = str1.getBytes();
        for (byte b : bytes) {
            //英文字母字符的ASCII值
            //除了ASCII值其他字符就是对应的编码值
            System.out.println(b);
        }
        System.out.println("===============================");
        String str3 = "  abc  bed  ";
        System.out.println(str3);
        //去掉首尾的空格
        System.out.println(str3.trim());
        //字符串有length方法
        System.out.println(str3.length());
        //数组有length属性
        System.out.println((new int[3]).length);
        System.out.println("=================================");
        char[] chars = str1.toCharArray();
        for (char c : chars) {
            System.out.println(c);
        }
        System.out.println("===============================");
        String str5 = "abCDfekQEEETtyr";
        //转换成小写
        System.out.println(str5.toLowerCase());
        //转成成大写
        System.out.println(str5.toUpperCase());
        ////验证码
        //拼接字符串
        System.out.println(str1.concat(str5));
        //contains包含某个字符
        System.out.println(str5.contains("CD"));
        String str4 = "abcde";
        //compareToIgnoreCase 比较字符串每个字符的时候忽略大小写
        System.out.println(str4.compareToIgnoreCase("AbCde"));
    }
}
复制代码

1、编写程序将"jdk" 全部变成大写 并输出到屏幕 截取”DK“并输出到屏幕

复制代码
/**
     * 1、编写程序将"jdk" 全部变成大写  截取”DK“并输出到屏幕
     */
    private static void transferUpper() {
        //定义str字符串变量,并把“jdk”赋值给str
        //String str = "jdk";
        /*//把str全部转换成大
        String upperStr = "jdk".toUpperCase();
        //截取字符串DK
        String substring = upperStr.substring(1);
        //打印最后的字符串
        System.out.println(substring);*/

        //优化上述代码
        //优化,先截取,然后再转大写字母
        //把str全部转换成大
        String substring = "jdk".substring(1);
        //截取字符串DK
        String upperStr = substring.toUpperCase();
        //打印最后的字符串
        System.out.println(upperStr);
    }
复制代码

 

String、StringBuffer、StringBuilder之间的差异与适用场景

  1、定义:有一个StringBuffer类,称为字符串缓冲区;所表示的也是一个字符序列;

  2、Java语言中的有一个StringBuffer类,称为字符串缓冲区;所表示的也是一个字符序列;

  这个类型必须用new创建对象,和String相反,它是可变的类;

  3、Java语言中的还有一个StringBuilder类,与StringBuffer兼容,但是不保证线程同步;

  4、String、StringBuffer、StringBuilder 区别

三个类的区别

  String类是不可变的,对象一旦被创建,就不能被修改;可以使用=直接赋值,此时使用常量池;也可以使用new创建,不使用常量池;

  StringBuffer是可变的,对象创建后,可以修改;必须使用new关键字 ,保证线程同步,多线程操作情况 建议使用StringBuffer;

  StringBuilder是可变的,是不保证线程同步,在单线程情况下使用比StringBuffer高效;必须使用new关键字

StringBuffer sbf1=new StringBuffer ("Etc");
StringBuffer sbf2=new StringBuffer (" Java");
sbf1.append(sbf2);
System.out.println(sbf1);//输出结果为:Etc Java

 

  证明了StringBuffer是一个可变的字符串类

复制代码
public class TestStringBuilder {
    public static void main(String[] args) {
        /*String str1 = "abc";
        String str2 = "bcd";
        //str1 = str1 + "bcd";
        String str3 = str1 + str2;  */// abcbcd
        //str3 = str1+str1+str1+str1+str1+str1
        //为了优化字符串拼接,出现StringBuilder和StringBuffer 这两个类
        //testStringBuilderAppend();
​
        StringBuilder sb = new StringBuilder();
        //StringBuilder的append方法在尾部添加
        sb.append("abc");
        sb.append("def");
        sb.append("ghdasdsadasdadadsddsd");
        //打印拼接之后字符串
        System.out.println(sb.toString());
        //在offset位置插入数据
        //sb.insert(1, "mmm");
        //删除,根据开始索引删除到截止索引,左闭右开,也就是说包括左边的索引值,不包括右边的索引值
        sb.delete(2, 5);
        //删除之后再次打印字符串
        System.out.println(sb.toString());
        //使用最后一个参数str字符串替换,开始索引到截止索引位置的字符串,左闭右开,也就是说包括左边的索引值,不包括右边的索引值
        sb.replace(2,5,"zzz");
        System.out.println(sb.toString());
        //返回存储的字符
        sb.reverse();
        System.out.println(sb.toString());
    }
​
    private static void testStringBuilderAppend() {
        //StringBuilder使用场景 就是大量字符串拼接之后带来的资源浪费问题
        StringBuilder sb = new StringBuilder();
        //StringBuilder的append方法在尾部添加
        sb.append("abc");
        sb.append("def");
        sb.append("gh");
        //toString把StringBuilder存储的字符串返回出去
        String join = sb.toString();
        System.out.println(join);
    }
}
复制代码

 

 

 

习题

1、编写程序将String类型字符串”test” 变为 “tset”.

复制代码
public class TestStringBuilderPra {
    public static void main(String[] args) {
        //1、编写程序将String类型字符串”test” 变为 “tset”.,使用StringBuilder
        //reverseStringBuilder();
        StringBuilder sb = new StringBuilder();
        sb.append("test");
        //替换
        sb.replace(1, 3, "se");
        //打印结果
        System.out.println(sb.toString());
    }
​
    private static void reverseStringBuilder() {
        StringBuilder sb = new StringBuilder();
        sb.append("test");
        //反转
        sb.reverse();
        //输出
        System.out.println(sb.toString());
    }
}
复制代码

 

posted @   carat9588  阅读(127)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示