Java笔记之常用类(十七)

一、包装类

1.基本介绍

包装类是针对八种基本数据类型相对应的引用类型,主要的特点就是调用该类中的方法

基本数据类型包装类
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble

除了Boolean和Character其余包装类的父类都是Number

2.装箱和拆箱

装箱:基本数据类型 转换成 包装类型
拆箱:包装类型 转换成 基本数据类型

jdk5以前需要手动的装箱和拆箱,jdk5以后可以自动装箱和拆箱

这里以int类型为例,其他类似

class test1{
    public static void main(String[] args) {
        //手动装箱 int -> Integer
        int a = 10;
        //方法一
        Integer integer = new Integer(a);
        //方法二
        Integer integer1 = Integer.valueOf(a);

        //手动拆箱 Integer -> int
        int i = integer.intValue();

        //jdk1.5以后自动拆装箱
        //自动装箱,底层代码仍是调用Integer.valueOf()
        Integer Integer2 = a;

        //自动拆箱,底层代码仍是调用integer.intValue()
        int a2 = Integer2;
    }
}

包装类与String之间的转换,这里以Integer为例

class test1{
    public static void main(String[] args) {
        //Integer -> String
        Integer i = 10; //这里是自动装箱
        //方法一
        String s = i +"";
        //方法二
        String s1 = i.toString();
        //方法三
        String s2 = String.valueOf(i);

        //String -> Integer
        String st = "123";
        //方法一
        Integer i1 = Integer.parseInt(st);  //本身返回的是Int类型,然后自动装箱为Integer
        //方法二
        Integer integer = new Integer(st);  //源码为调用它的一个构造器

        //常用的方法
        System.out.println(Integer.MAX_VALUE);  //表示的最大值
        System.out.println(Integer.MIN_VALUE);  //表示的最小值
        System.out.println(Character.isDigit('c')); //判断是不是数字
        System.out.println(Character.isDigit('c')); //判断是不是字母
        System.out.println(Character.isUpperCase('c')); //判断是不是大写
        System.out.println(Character.isLowerCase('c')); //判断是不是小写
    }
}

面试题1

Object x = true ? new Integer(1) : new Double(2.0);
System.out.println(x);  //因为x后面的是三元运算符,所以数据类型取最大的,

面试题2

class test1{
    public static void main(String[] args) {
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System.out.println(i == j); //false,因为是new了两个不同的对象

        /*
        Integer m = 1完成了自动装箱功能,调用了Integer.valueOf(1)方法
        该方法源码的意思为:
        如果给的这个数在-128-127之间那么直接从返回
        如果给的这个数不在-128-127之间,那么要new Integer(i),
        如果是new Integer(i)的话就是两个不同的对象了
         */
        Integer m = 1;  //底层 Integer.valueOf(1);
        Integer n = 1;  //底层 Integer.valueOf(1);
        System.out.println(m == n); //true

        Integer m1 = 128;  //底层 Integer.valueOf(1);
        Integer n1 = 128;  //底层 Integer.valueOf(1);
        System.out.println(m1 == n1); //false
        
        int x = 128;
        Integer y = 128;
        System.out.println(x == y); //true 因为x为基本数据类型,所以比较的是值是否相等
    }
}

二、String类☆

1.基本介绍

  1. String 对象用于保存字符串,也就是一组字符序列
  2. 字符串的字符使用 Unicode 字符编码,一个字符(不区分字母还是汉字)占两个字节
  3. String 类有很多构造器,构造器的重载,常见的有:
    ①String s1 = new String();
    ②String s2 = new String(String original);
    ③String s3 = new String(char[] a);
    ④String s4 = new String(char[] a,int startIndex,int count);
    ⑤String s5 = new String(byte[] b);
  4. String类实现了接口Serializable和Comparable
    ①Serializable:String 可以串行化,可以在网络传输
    ②Comparable :String 对象可以比较大小
  5. String 是 final 类,不能被其他的类继承
  6. String 有个属性为 private final char value[],用于存放字符串内容,在源码的114行;注意:value是一个final可惜,不可以修改,即value不能指向新的地址,但是单个字符内容是可以修改的,代码演示如下
class test1{
    public static void main(String[] args) {
        final char[] value = {'a','b','c'};
        char[] value1 = {'t','o','m'};
        value[0] = 'H'; //final char[] value = {'H','b','c'};
//        value = value1;   //错误的
    }
}

2.创建String对象的两种方式

方式一:直接赋值 如:String s = “java”;
方式二:调用构造器 如:String s = new String(“java”);

两者之间的区别:

方式一:先从常量池查看是否有"java"数据空间,如果有就指向,如果没有就重写创建。s最终指jvm方法区常量池中的空间地址
方式二:先在jvm堆中创建空间,里面维护了 private final char value[] 属性,然后指向常量池"java"数据空间,如果有通过value指向,如果没有则重新创建。最终指向的是堆中的空间地址

测试题

class test1{
    public static void main(String[] args) {
        //equals比较两个值是否相等
        //intern方法最终返回是常量池的地址
        //测试一  a和b都指向常量池的同一个地址
        String a = "java";
        String b = "java";
        System.out.println(a.equals(b)); //true
        System.out.println(a == b); //true

        //测试二
        String a1 = new String("java");
        String b1 = new String("java");
        System.out.println(a1.equals(b1));  //true
        System.out.println(a1 == b1);   //false 创建了两个对象

        //测试三
        String a2 = "java";
        String b2 = new String("java");
        System.out.println(a2.equals(b2));  //true
        System.out.println(a2 == b2);   //false 一个常量池,一个堆中对象
        System.out.println(a2 == b2.intern());  //true
        System.out.println(b2 == b2.intern());  //false

        //测试四
        String a3 = "Test";
        String b3 = "java";
        String c3 = new String("java");
        System.out.println(a3 == b3);   //false
        System.out.println(b3.equals(c3));  //true
        System.out.println(b3 == c3);   //false

        //测试五
        test test1 = new test();
        test test2 = new test();
        test1.name = "java";
        test2.name = "java";
        System.out.println(test1.name.equals(test2.name));  //true
        System.out.println(test1.name == test2.name);   //true
        System.out.println(test1.name == "java");   //true
    }
}
class test{
    String name;
}

3.String字符串的特性

  1. String是一个final类,代表不可变的字符系列
  2. 字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的

面试题

class test1{
    public static void main(String[] args) {
        //下面代码创建了几个对象?  2
        String s = "test";
        s = "ssss";

        //下面代码创建了几个对象?  1
        String s1 = "java" + "test";    //在底层编译器会优化 String s1 = "javatest";

        //下面代码创建了几个对象?  3
        String s2 = "java";
        String s3 = "test";
        /*
        debug追源码
        1.先创建一个StringBuilder x = StringBuilder()
        2.执行x.append("java");
        3.执行x.append("test");
        4.String s4 = x.toString() 而toString里面是有一个new的过程
         */
        String s4 = s2 + s3;

        //测试题
        String s5 = "javatest";
        System.out.println(s4 == s5);   //false
        String s6 = "java"+"test";
        System.out.println(s5 == s6);   //true,因为直接指向常量池中的同一个地址
    }
}

String s6 = “java”+“test”; 常量相加看池,String s4 = s2 + s3; 变量相加看堆

测试题

class test1{
    public static void main(String[] args) {
        String s = "java";      //指向常量池中的 "java"
        String s1 = "test";     //指向常量池中的 "test"
        String s2 = "javatest";     //指向常量池中的 "javatest"
        String s3 = (s+s1).intern();    //指向常量池中
        System.out.println(s2 == s3);   //true
        System.out.println(s2.equals(s3));  //true
    }
}

4.String的常用方法

方法名功能
equals区分大小写,判断内容是否相等
equalslgnoreCase不区分大小写,判断内容是否相等
length获取字符的个数,字符串的长度
indexOf获取字符在字符串中第1次出现的索引,如果找不到返回-1
lastIndexOf获取字符在字符串中最后1次出现的索引,如果找不到返回-1
substring截取指定范围的字串
trim去前后空格
charAt获取某索引处的字符,注意不能使用Str[index]这种方式
toUpperCase转化为大写
toLowerCase转化为小写
concat字符串的拼接
replace替换字符串中的字符
split分割字符串
compareTo比较两个字符串的大小
toCharArray转换成字符数组
format格式字符串

三、StringBuffer类☆

1.基本介绍

引入:String类是保存字符常量的,每次更新都需要重新开辟空间,效率较低,因此java设计者提供了StringBuffer和StringBuilder来增强String的功能,并提高效率

StringBuffer代表可变的字符序列,可以对字符串内存进行增删,很多方法与String相同,但StringBuffer是可变长度的

StringBuffer是一个容器

StringBuffer解析:

  • StringBuffer 的直接父类是 AbstractStringBuilder
  • StringBuffer 实现了 Serializable,即 StringBuffer 的对象可以串行化(进行网络传输)
  • 在父类中 AbstractStringBuilder 有个属性 char[] value,不是 final,该value数组存放字符串内容,即存放在堆中
  • StringBuffer是一个 final 类,不能被继承

String与StringBuffer的比较

  1. String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低
  2. StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高

StringBuffer常用构造器

  • StringBuffer():构造一个不带字符的字符串缓冲区,其初始容量为16个字符
  • StringBuffer(int capacity):构造一个不带字符,但具有指定初始容量的字符串缓冲区,即对char[]大小进行指定
  • StringBuffer(String str):构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容

String和StringBuffer相互转换

class test1{
    public static void main(String[] args) {
        //String -> StringBuffer
        //方式一
        String s = "java";
        StringBuffer stringBuffer = new StringBuffer(s);
        //方式二
        StringBuffer stringBuffer1 = new StringBuffer();
        stringBuffer1.append(s);

        //StringBuffer -> String
        //方式一
        StringBuffer stringBuffer2 = new StringBuffer("java");
        String s1 = stringBuffer2.toString();

        //方式二
        String s2 = new String(stringBuffer2);
    }
}

2.StringBuffer常用方法

增、删、改、插以及获取长度等

class test1{
    public static void main(String[] args) {
        //增
        StringBuffer s = new StringBuffer("java");
        s.append(",");
        s.append("test").append(1);
        System.out.println(s);

        //删
        StringBuffer s1 = new StringBuffer("java");
        s1.delete(0, 2);
        System.out.println(s1);

        //改
        StringBuffer s2 = new StringBuffer("java");
        s2.replace(0,1,"AA");
        System.out.println(s2);

        //插
        StringBuffer s3 = new StringBuffer("java");
        s3.insert(1,"BB");
        System.out.println(s3);
        //获取长度
        System.out.println(s3.length());
    }
}

四、StringBuilder类☆

1.基本介绍

StringBuilder一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder 不是线程安全) 该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。其主要用法和StringBuffer一样

如果可以使用StringBuilder ,建议优先采用该类,因为在大多数实现中,它比StringBuffer要快

在StringBuilder上的主要操作是append和insert方法,可重载这些方法,以接收任意类型的数据

StringBuilder解析:

  • StringBuffer 的直接父类 是 AbstractStringBuilder
  • StringBuffer 实现了 Serializable, 即 StringBuffer 的对象可以串行化
  • StringBuilder 对象字符序列仍然是存放在其父类 AbstractStringBuilder 的 char[] value;因此,字符序列是堆中
  • StringBuilder 的方法,没有做互斥的处理,即没有 synchronized 关键字,因此在单线程的情况下使用

2.String、StringBuffer 和 StringBuilder 的比较

  1. StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法一样
  2. String:不可变字符序列,效率低,但是复用率高
  3. StringBuffer:可变字符序列、效率较高(增删)、线程安全
  4. StringBuilder:可变字符序列、效率最高、线程不安全

3.总结☆

  1. 如果字符串存在大量的修改操作,一般使用StringBuffer和StringBuilder
  2. 如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder
  3. 如果字符串存在大量的修改操作,并在多线程的情况,使用StringBuffer
  4. 如果我们字符串很少修改,被多个对象引用,使用String,比如 配置信息等
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王博1999

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值