可变字符串

可变字符串

可变字符串采用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);
        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);

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);
xjc1234.0java.util.Random@74a14482

根据结果可以看出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);

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()方法将原始类型转换为包 装类对象

拆箱

概念:

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

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

自动装箱池

//以下代码的输出结果: 
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));

如果通过调用构造方法创建的包装类对象,属于不同地址,使用==比较的结果为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]);
            }
        }

解法二:

  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 + "次");
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值