• 可变字符串


    可变字符串

    可变字符串采用toString()转化为不可变字符串(转换后用于比较值是否相等)

    因为String类在创建对象时,值不可变。在频繁更新值时就是在内存中频繁创建对象,效率很低。这时就需要可变字符串

    运行下面代码,我们就可以发现其效率差距,能清晰看出String在频繁更新时的效率低,浪费内存空间

            String str = "";
            long begin = System.currentTimeMillis();
            for (int i = 0; i < 10000; i++) {
                str += i;
            }
            long end = System.currentTimeMillis();
    		//输出的是循环所用时间
            System.out.println(end - begin);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
            StringBuilder sb = new StringBuilder();
            long begin = System.currentTimeMillis();
            for (int i = 0; i < 10000; i++) {
                sb.append(i);
            }
            long end = System.currentTimeMillis();
            //输出的是循环所用时间
            System.out.println(end - begin);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    StringBuilder类

    概念

    用于表示可变字符串的一个类,是非线程安全的,建议在单线程环境下使用,效率略高于

    StringBuffer。

    构造方法
    new StringBuilder()默认创建一个长度为16的字符数组
    new StringBuilder(int i)创建一个长度为i的字符数组
    new StringBuilder(String str)创建一个长度为str.length()+16的数组
            StringBuilder sb = new StringBuilder();
            sb.append("xjc");
            sb.append(123);
            sb.append(4.0);
            sb.append(new Random());
            System.out.println(sb);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    xjc1234.0java.util.Random@74a14482
    
    • 1

    根据结果可以看出append()是用于字符串添加内容,可以是任何内容

    常用方法(在使用 StringBuilder 类时,每次都会对 StringBuilder 对象本身进行操作,而不是生成新的对象,不同于String的方法,调用后结果不变):

            sb.append("qwert");
            //删除[0,3)
            sb.delete(0,3);
            //删除指定位置
    		sb.deleteCharAt(1);
            System.out.println(sb);
            //从0开始插入
            sb.insert(0,"asd");
            System.out.println(sb);
            //[0,3)用*替换
            sb.replace(0,3,"*");
            System.out.println(sb);
            //反转
            sb.reverse();
            System.out.println(sb);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    StringBuffer类

    用于表示可变字符串的一个类,是线程安全的,建议在多线程环境下使用,效率略低于StringBuilder。

    StringBuilder和StringBuffer中的方法作用都一致,只不过StringBuffer中的方法使用了synchronized关

    键字修饰,表示一个同步方法,在多线程环境下不会出现问题。

    StringBuilder是一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。

    StringBuiffer也代表可变字符串对象。实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同。不同的是:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高。

    包装类

    八个基本数据类型都有包装类

    装箱

    概念:所有包装类都有一个静态方法valueOf(原始类型),将某个原始类型的数据转换为相应的包装类对象,这个过程称为装箱

    //手动装箱 
    int i=123;//定义一个原始类型的数据 
    Integer aInteger=Integer.valueOf(i);//调用包装类的valueOf()方法将原始类型转换为包 装类对象
    
    • 1
    • 2
    • 3

    拆箱

    概念:

    所有包装类都有一个原始类型Value()方法,用于将包装类对象转换为原始类型,这个过程称为拆箱

    //手动拆箱 
    Integer aInteger=new Integer(123);//创建一个包装类对象 
    int i = aInteger.intValue();//调用包装类的"原始类型Value()"方法将其转换为原始类型
    
    • 1
    • 2
    • 3
    //自动装箱 
    Integer aInteger=123; 
    //自动拆箱 
    int i=aInteger;
    
    • 1
    • 2
    • 3
    • 4

    自动装箱池

    //以下代码的输出结果: 
    Integer i1=new Integer(100); 
    Integer i2=new Integer(100); 
    //i3中保存的100,在byte范围内,保存在"自动装箱池"中 
    Integer i3=100; 
    //i4中保存的100,在byte范围内,如果有现成的,直接引用 
    Integer i4=100; 
    //i5和i6中保存的200,超出byte范围,会创建两个新对象 
    Integer i5=200; 
    Integer i6=200; 
    System.out.println(i1==i2);//false 
    //i3和i4保存的是同一个地址,所以是true 
    System.out.println(i3==i4);//true 
    //i5和i6保存的是两个地址,所以是false 
    System.out.println(i5==i6);//false 
    
    //涉及包装类的比较,要使用包装类重写了的equals方法 
    System.out.println(i5.equals(i6));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    如果通过调用构造方法创建的包装类对象,属于不同地址,使用==比较的结果为false

    自动装箱的形式,赋值范围在-128~127之间,将这个范围内的数保存到了"自动装箱池"中,

    所以两个包装类对象保存的数在这个范围内时,使用同一个地址。超过这个范围,使用的不是同一个地址。

    所以我们在引用类型之间比较,一定不要使用**==,要使用重写的equals**方法

    习题

    输入一段字符串,拼接n次,统计每个字符出现的次数

    解法一(不能统计中文):

            Scanner sc = new Scanner(System.in);
            System.out.println("输入一段英文字符:");
            String str = sc.next();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 20; i++) {
                sb.append(str);
            }
            char[] chars = sb.toString().toCharArray();
            int[] list = new int[123];
    
            for (int i = 0; i < chars.length; i++) {
                //char[0]: a
                //chars[i]是每个字母对应的ascii码,即是list[a]--list[97]
                list[chars[i]]++;
            }
            for (int i = 65; i < list.length; i++) {
                if (list[i] != 0){
                System.out.println((char)i+":"+list[i]);
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    解法二:

      Scanner sc = new Scanner(System.in);
            System.out.println("输入一段英文字符:");
            String str = sc.next();
            //定义一个字符数组存储字符串出现的单词
            char[] letters = new char[100];
            for (int i = 0;i < str.length();i++){
                //取出字符串每一位
                letters[i] = str.charAt(i);
                //循环判断新添加的一位和前面的是否重复
                for (int j = 0;j < i;j++){
                    //重复让它为0
                    if (letters[i] == letters[j]) {
                        letters[i] = 0;
                        break;
                    }
                }
            }
    //        for (char l : letters) {
    //            if (l != 0){
    //                System.out.println(l);
    //            }
    //        }
            StringBuilder sb = new StringBuilder();
            System.out.println("输入拼接次数");
            int n = sc.nextInt();
            //将前面的字符串拼接
            for (int i = 0; i < n; i++) {
                sb.append(str);
            }
            //StringBuilder转化为字符串
            String str1 = sb.toString();
            //字符串转化为字符数组
            char[] str2 = str1.toCharArray();
            //将前面提取出来的每个字母循环和拼接后的进行比较
            for (char letter : letters) {
                if (letter != 0) {
                    int count = 0;
                    for (char c : str2) {
                        if (letter == c) {
                            count++;
                        }
                    }
                    System.out.println(letter + ": " + count + "次");
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
  • 相关阅读:
    学习记录十六
    【Flink系列】开启jdbc批量写入
    二叉树经典oj面试题
    Java“牵手”淘宝店铺商品列表页数据采集+淘宝店铺商品上传接口,淘宝API接口申请指南
    【目标】新学期计划与目标
    每章一篇博客带你拿下吉林大学JAVAEE期末(二)
    [Linux系统编程]_进程的通信(三)
    文心一言 VS 讯飞星火 VS chatgpt (119)-- 算法导论10.3 4题
    和数软件助力能源领域新场景新思路
    kubernetes(2)
  • 原文地址:https://blog.csdn.net/qq_55691662/article/details/126035964