Java包装类(Integer和String)

Integer类

将基本数据类型包装成类对象

Integer a = new Integer(10);
Integer b = Integer.valueOf(12);

将包装类对象转换成基本数据类型

int c = b.intValue();
double d = b.doubleValue();

将字符串转换成包装类对象

Integer e = new Integer("9999");
Integer f = Integer.parseInt("55555");

将包装类对象转换成字符串

String str=Integer.toString(100);

常见的常量

System.out.println("Integer里最大的常量:"+Integer.MAX_VALUE);
System.out.println("Integer里最小的常量:"+Integer.MIN_VALUE);

自动装箱

Integer a = 100;

相当于编译器自动为你执行下Integer b = Integer.valueOf(100);

自动拆箱

int c = a;

相当于编译器自动执行int c = a.intValue();

关于[-128,127]之间的缓存问题

首先我们来看一段代码,思考一下结果是什么?

Integer int1 = Integer.valueOf(123);
Integer int2 = 123;
System.out.println(int1.equals(int2));
System.out.println(int1 == int2);

int1.equals(int2)结果为true很简单,两者值相等,那么int1 == int2呢?
很多人会以为答案是false,因为int1和int2是两个不同对象,它们在堆中所处空间不一样,但是结果是true。为什么会这样呢?
我们打开Integer的源码,看到valueOf方法里这样一段代码:

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

这里的cache是什么呢?我们顺藤摸瓜:

static final int low = -128;
static final int high;
static final Integer cache[];
cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

我们对此进行分析,原来Integer一开始创建了一个cache数组,这个数组里有[-128,127]的Integer对象,当我们创建在这个范围的实例时,valueOf方法就会找到相应的实例,所以我们创建两个大小一样的对象其实是指向同一引用

String类

String 类对象代表不可变的Unicode字符序列,因此我们可以将String对象称为“不可变对象”。
在这里插入图片描述
String类常用的方法有:

  1. String类的下述方法能创建并返回一个新的String对象: concat()、 replace()、substring()、 toLowerCase()、 toUpperCase()、trim()。

  2. 提供查找功能的有关方法: endsWith()、 startsWith()、 indexOf()、lastIndexOf()。

  3. 提供比较功能的方法: equals()、equalsIgnoreCase()、compareTo()。

  4. 其它方法: charAt() 、length()。

StringBuffer和StringBuilder

StringBuffer和StringBuilder非常类似,均代表可变的字符序列。 这两个类都是抽象类AbstractStringBuilder的子类,方法几乎一模一样。我们打开AbstractStringBuilder的源码:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char value[];
//以下代码省略
}

显然,内部也是一个字符数组,但这个字符数组没有用final修饰,随时可以修改。因此,StringBuilder和StringBuffer称之为“可变字符序列”。
两者的区别:

  • StringBuffer JDK1.0版本提供的类,线程安全,做线程同步检查, 效率较低

  • StringBuilder JDK1.5版本提供的类,线程不安全,不做线程同步检查,因此效率较高。 建议采用该类。

一些StringBuffer方法:

StringBuffer str3 = new StringBuffer("abcd");
str3.append("e");//在尾部添加字符串
System.out.println(str3);

str3.reverse();//将字符串逆序
System.out.println(str3);

str3.setCharAt(1, 'B');//将该下标的字符替代
System.out.println(str3);

str3.insert(0,"A").insert(1, "BC");//链式调用,核心就是调用了return this;
System.out.println(str3);

str3.delete(0, 2);//删除[0,2)区间的字符
System.out.println(str3);

结果:
dnimg.cn/2020041319241355.png)

可变字符序列和边看边字符序列的陷阱

/**使用String进行字符串的拼接*/
String str = "";
//本质上使用StringBuilder拼接,但是每次拼接会产生新的字符串对象
long num1 = Runtime.getRuntime().freeMemory();//获取系统剩余内存
long time1 = System.currentTimeMillis();//获取系统当前时间
for(int i=0;i<5000;i++) {
	str = str + i;//相当于产生了10000个对象
}
long num2 = Runtime.getRuntime().freeMemory();
long time2 = System.currentTimeMillis();
System.out.println("String占用内存"+(num1-num2));
System.out.println("String占用时间"+(time2-time1));

/**使用StringBuilder进行字符串的拼接*/
StringBuilder str1 = new StringBuilder("");
long num3 = Runtime.getRuntime().freeMemory();
long time3 = System.currentTimeMillis();
for(int i=0;i<5000;i++) {
	str1.append(i);//相当于产生了10000个对象
}
long num4 = Runtime.getRuntime().freeMemory();
long time4 = System.currentTimeMillis();
System.out.println("String占用内存"+(num3-num4));
System.out.println("String占用时间"+(time4-time3));

结果:
在这里插入图片描述
使用String拼接产生大量对象会耗费很多内存和时间,因此非常不可取,而使用append消耗时间和内存忽略不计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值