java包装类。

包装类介绍

        Java的包装类(Wrapper Classes)是Java语言为八种基本数据类型(byte, short, int, long, float, double, char, boolean)提供的对应类。这些包装类允许我们将基本数据类型当作对象来处理,并提供了许多有用的方法和常量。以下是每个基本数据类型对应的包装类:

  1. Byte:对应基本数据类型byte
  2. Short:对应基本数据类型short
  3. Integer:对应基本数据类型int
  4. Long:对应基本数据类型long
  5. Float:对应基本数据类型float
  6. Double:对应基本数据类型double
  7. Character:对应基本数据类型char
  8. Boolean:对应基本数据类型boolean

包装类的主要用途

  1. 提供了一系列实用的方法:例如,Integer类提供了将字符串转换为整数的方法(Integer.parseInt()),Double类提供了比较两个浮点数是否相等的方法(Double.compare())等。
  2. 实现了数据类型之间的转换:包装类提供了将基本数据类型转换为字符串、将字符串转换为基本数据类型等方法,方便了数据类型的转换操作。
  3. 支持泛型操作:在Java集合框架中,由于泛型只能接受类类型,而不能接受基本数据类型,因此我们需要使用包装类来存储和操作基本数据类型。
  4. 提供了常量:例如,Integer类提供了表示最大值、最小值、字节大小等常量。

        此外,从Java 5开始,引入了自动装箱和拆箱机制,这使得基本数据类型和其对应的包装类之间的转换变得更加便捷。装箱是将基本数据类型转换为对应的包装类对象的过程,而拆箱则是将包装类对象转换回对应的基本数据类型的过程。
        自动装箱:将基本数据类型自动转换为对应的包装类对象。
        自动拆箱:将包装类对象自动转换为对应的基本数据类型。

public class A {
    public static void main(String[] args) {
        //JDK5之前
        //手动装箱
        int int1 = 10;
        Integer integer1 = new Integer(int1); // 使用构造函数进行装箱
        Integer integer2 = Integer.valueOf(int1); // 使用静态工厂方法进行装箱
        //手动拆箱
        Integer integer3 = 10;
        int int3 = integer3.intValue(); // 使用intValue()方法进行拆箱
        //--------------------------------------------------------
        //JDK5之后
        //自动装箱
        int int4 = 10;
        Integer integer4 = int4;//系统自动调用new Integer(int4)
        //自动拆箱
        Integer integer5 = 100;
        int int5 = integer5;//系统自动调用integer5.intValue()进行拆箱
    }
}

        其他类的用法与其相似,在此不再赘述。

隐式的精度提升和自动装箱

        例如在三元运算符中,如果在表达式中混合使用不同的基本数据类型时,较低精度的类型会被自动提升为较高精度的类型。例如,当int和double一起使用时,int会被自动提升为double,因为double具有更高的精度。这种提升是自动的,无需显式转换。

public class A {
    public static void main(String[] args) {
       int num1=10;
       double num2=11;
       //方法一
       System.out.println((true)?num1:num2);
       //方法二
       if(true)
           System.out.println(num1);
       else
           System.out.println(num2);
    }
}

执行结果:

10.0

10

        看似两者方法执行了相同的操作,但三元运算符会自动将精度较低的 int1 进行精度提升。

        这种情况也同样适用自动装箱:将数据类型由 double 替换为 Integer,n1 也会因为三元运算符由int转换为Integer。但这个过程是自动装箱并不涉及精度的提升,它只是将基本数据类型转换为其对应的包装类对象。

包装类和String类相互转换

包装类(Integer)转String

1、使用连接运算符"+": 使用+运算符将基本数据类型或它们的包装类与字符串连接起来,这会自动将非字符串类型转换为字符串。

2、使用toString方法:所有的包装类都重写了Object类的toString()方法,以返回表示该对象的字符串。

3、使用String.valueof()方法: String 类提供了一个静态的valueOf()方法,该方法可以接受各种类型(包括基本数据类型和它们的包装类)的参数,并返回其字符串表示。

public class Go {//主方法
    public static void main(String[] args) {
    Integer i=10;
    //使用连接运算符"+"
    String str1=i+"";
    //使用toString()方法
    String str2=i.toString();
    //使用String.valueOf()方法
    String str3=String.valueOf(i);
    }
}

String转包装类

1、使用构造方法创建新对象:每个包装类都提供了一个接受字符串参数的构造方法,用于将字符串转换为该包装类的实例。

2、使用包装类中的的方法:例如Integer.parseInt()、Integer.valueOf()。这两个方法虽然返回的都是整形变量,但前者返回的是基本数据类型 int,后者返回的是包装类 Integer 对象。

public class Go {//主方法

    public static void main(String[] args) {
        String str="123";
        //使用构造器,返回一个新的Integer类对象
        Integer num1 = new Integer(str);
        //使用包装类方法
        Integer num2 = Integer.parseInt(str);// 返回int型变量,再自动装箱
        Integer num3 = Integer.valueOf(str);// 返回包装类对象Integer
    }
}

Integer创建机制

        在Integer类中有着一个预存数组。这个数组包含 -128 到 127(包括两端)之间所有的Integer 对象。当你创建 Integer 类对象时,如果值处于该范围之间,系统就会返回缓存中的对象实例,而不是创建一个新的对象。在这个范围之外时,系统则会创建新实例并返回。

        但需要注意的是当你使用 new Integer( int类变量 ) 构造函数来显式地创建一个新的Integer对象时。new 关键字总是会创建一个新的对象,即使该值已经存在于缓存中。

public class A {
    public static void main(String[] args) {
        Integer a = Integer.valueOf(127);
        Integer b = Integer.valueOf(127);
        System.out.println(a == b);  
        // 输出 true,因为 a 和 b 在范围内,引用相同的对象
        Integer c = Integer.valueOf(128);
        Integer d = Integer.valueOf(128);
        System.out.println(c == d);  
        // 输出 false,因为 c 和 d 在范围外,是不同的对象实例
        Integer e=new Integer(100);
        Integer f=new Integer(100);
        System.out.println(e==f);
        // 输出 false,因为new关键字会自动创建不同的对象实例
    }
}

String类 

创建方式

在Java中,创建String对象的常用方式有两种:

  1. 直接赋值

        这是最简单和最常用的方式。
        当使用双引号直接给String变量赋值时,Java会在字符串常量池中查找是否已经存在相同的字符串。
        如果存在,则直接引用该字符串;
        否则,在字符串常量池中创建一个新的字符串对象。
        注意,String str3 = "str1" + "str2"; 这行代码的结果和String str3 = "str1str2";是等价的。在这两种情况下,str3都会指向字符串常量池中的"str1str2"字符串。

String str1 = "Hello";
//等同于
String str1="He"+"llo";
  1. 使用new关键字

        使用new关键字创建一个新的String对象,该对象总是位于堆内存中,并且不会在字符串常量池中查找或创建。

String str2 = new String("Hello");

注意事项

  1. String用于保存保存字符串,也就是一组字符序列
  2. 字符串中的字符使用Unicode字符编码,一个字符(不区分字母或汉字)占两个字节
  3. String类有很多构造器,构成了构造器的重载,常用的构造器:
    1. String(): 创建一个空字符串。
    2. String(String original): 创建一个字符串。
    3. String(char[] value): 使用字符数组初始化字符串。
    4. String(byte[] bytes): 使用字节数组初始化字符串(假设字节是默认的字符集)。
    5. String(char[] value, int offset, int count): 使用字符数组的一部分初始化字符串。
  4. String实现了三个接口:
    1. Serializable:String可以串行化,即可以在网络上传输
    2. Comparable:允许String对象进行比较
    3. CharSequence:各种常用方法
  5. String类是final类,不可被其他类继承
  6. String有属性private final char value[];用于存放字符串内容,因其被final修饰,所以String对象所指向的地址无法被修改。(即String一旦创建,所指向的地址就已确定,无法再指向新的地址。它的内容也是不可变的,每次对 String 的修改操作(如连接、替换等)实际上都会创建一个新的 String 对象。)
            String str = "Hello";  
            // str 现在是 "Hello",我们不能改变它包含的内容  
            // 下面的代码会创建一个新的 String 对象,而不是修改 str  
            str = str + " World"; // 现在 str 是 "Hello World"
            char[] str1 = {'a','a','a'};//普通字符串
            //使用字符数组模拟String对象
            final char[] str2 = {'b','b','b'};
            final char[] str3 = {'c','c','c'};
            str2[0]=str3[0];//正确,内容可被修改
            str1=str2;//正确,使str1指向str2,
            str2=str3;//错误,有final修饰,str2所指向的地址不可被修改

String常用方法

1、equals():区分大小写,判断内容是否相等

2、equalsIgnoreCase():不区分大小写,判断内容是否相等

3、indexOf():获取指定字符或字符串在字符串中第一次出现的索引(索引从0开始),找不到则返回-1

4、lastIndexOf():获取指定字符或字符串在字符串中最后一次出现的索引(索引从0开始),找不到则返回-1

5、substring():截取指定范围的字符串

String str="0123456789";
System.out.println(str.substring(2));
//从索引"2"开始,截取后面所有内容,输出23456789
System.out.println(str.substring(2,5));
//从索引"2"开始,截取到索引"'5'-1"的内容,输出234

6、trim():去除前后空格

7、charAt():获取字符串指定位置的字符

8、toUpperCase():全部转换为大写,toLowerCase()全部转换为小写

9、concat():连接字符串

10、replace():替换指定字符串

String str = "no.1 no.2 no.3";
System.out.println(str.replace("no","No"));
//将str中所有的"no"替换为"No"

11、split():基于指定的正则表达式或字符来拆分字符串。

//一、基本语法
//以指定字符或字符串来划分原字符串
String str ="yes or no";
String[] str1=str.split(" ");
//将str以" "来划分str1[0]=yes,str1[1]=or,str1[3]=no
//二、使用limit参数
//以指定字符或字符串来划分原字符串,且划分为limit份
String str ="yes or no";
String[] str1=str.split(" ",2);
//将str以" "来划分str1[0]=yes,str1[1]=or,str1[3]=no
//三、使用正则表达式
//如果以特殊字符对字符串进行划分,需加入转义符\
String str ="E\\java\\test";
String[] str1=str.split("\\\\");
//因为特殊字符为"\\",有两个,所以需要加入两个转义符,即"\\\\"
//将str以"\\"来划分str1[0]=E,str1[1]=java,str1[3]=test

​​​​​12、toCharArray():将字符串转化为字符数组

        该方法会逐个比较两字符串的编码大小,并返回前者编码减去后者编码的结果;如果两字符串前缀相同(如qwer和qwerty),则返回两字符串长度相减的值;相同则返回0。

StringBuffer类

  • StringBuffer代表可变的字符序列,与String类不同,它可以对字符串内容进行增删操作。
  • StringBuffer的直接父类是AbstractStringBuilder类,并且实现了Serializable接口,意味着StringBuffer的对象可以串行化。
  • StringBuffer内部使用一个char[]数组来存放字符串内容,该数组不是final修饰的,因此内容可以变化。
  • StringBuffer是一个final类,不能被其他类继承。

String和StringBuffer的区别

  1. String保存的是字符串常量,里面的值不能更改;StringBuffer保存的是字符串变量,里面的值可以更改。
  2. String每次更新实际上都是更改地址,效率较低(栈->堆->常量池);StringBuffer的更新实际上可以更新内容,不用每次都更新地址,效率较高(栈->堆)。

构造方法 

StringBuffer()

        创建一个不带任何字符的StringBuffer对象,其初始容量为16个字符。

StringBuffer str1 = new StringBuffer();
//str1容量为16个字符

StringBuffer(int)

        创建一个不带任何字符的,但具有指定初始容量的StringBuffer对象

StringBuffer str2 = new StringBuffer(7);
//str2容量为7个字符

StringBuffer(String)

        创建一个StringBuffer对象,其内容初始化为字符串String,并增加16个字符的容量。

StringBuffer str3 = new StringBuffer("hello");
//字符串"hello"长度为5,则str3容量为5+16=21个字符

String和StringBuffer相互转换

        在Java中,String类对象实例一旦被创建,它的内容就不能被改变。而 StringBuffer 类是可变的。因此,我们不能直接将String类实例直接转换为StringBuffer类实例,因为两者是两个完全不同的类。但你可以通过其他方法来实现这一转换。

String转StringBuffer

1、使用StringBuffer的构造器
String s="hello";
StringBuffer str = new StringBuffer(s);

        但要注意这里str才是StringBuffer类对象,s仍是String类对象,未发生任何改变。

2、使用append方法
String s="hello";
//创建一个空的StringBuffer类对象
StringBuffer str1 = new StringBuffer();
//使用append方法将“s”赋给“str1”
str1=str1.append(s);

         这并不是直接将 String 类转换为 StringBuffer 类,而是先创建一个空的 StringBuffer 类对象,再使用 append 方法将 String 的内容添加到其中。

StringBuffer转String

1、使用toString()方法
StringBuffer str=new StringBuffer("hello");
String s=str.toString();
2、使用String类的构造器
StringBuffer str=new StringBuffer("hello");
String s = new String(str);

StringBuffer类常用方法

        其常用方法也离不开增、删、查、改四种基础方法

增:append()方法

         向字符串的末尾追加指定的内容,可以接受不同类型的参数,并将它们转换为字符串表示形式后追加到缓冲区末尾:

        StringBuffer str = new StringBuffer("hello");
        str.append(",world.");
        str.append("我").append(100).append(true).append(10.5);

        最终str的值:hello,world.我100true10.5 

删:delete()方法

        删除字符串中指定位置的字符或指定范围内的字符。deleteCharAt(int index)方法用于删除指定索引处的字符,而delete(int start, int end)方法用于删除从 start 到 end 之间的字符。

StringBuffer str = new StringBuffer("0123456789");
str.deleteCharAt(8);//删除“8”,str为012345679
str.delete(2,5);//删除str[2]-str[4],str为015679

查:indexOf()方法

        其使用方法等同于String类中的indexOf方法,如果找到指定字符或字符串,则返回首次出现的索引(索引从0开始),找不到则返回-1。同样的,也有lastIndexOf()方法:获取指定字符或字符串在字符串中最后一次出现的索引(索引从0开始),找不到则返回-1。

改:replace()方法

        替换字符串中指定范围内的字符序列。replace(int start, int end, String str)方法用于将指定范围内的字符替换为新的字符串。

StringBuffer str = new StringBuffer("0123456789");
str.replace(2,4,"hello");//将[2,4)序列的字符替换为指定字符串
//str的值:01hello456789
str.replace(2,7,"23");//将[2,7)序列的字符替换为指定字符串
System.out.println(str);
//str的值:0123456789

        如果方法内两int变量的值相同,则会直接在该序列后添加指定字符串,不会删除原字符串中的内容。

StringBuffer str = new StringBuffer("0123456789");
str.replace(2,2,"hello");//两int变量的值相同
//str的值:01hello23456789

插:insert()方法

        在字符串的指定位置之前插入指定的内容,该位置以及之后的内容自动后移。

StringBuffer str = new StringBuffer("0123456789");
str.insert(2,"sss");//在“2”之前插入内容“sss”
//str的值:01sss23456789

判断长度:length()方法

         返回字符串的当前长度,即其中包含的字符数。

StringBuilder类

        StringBuilder是一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API ,但不保证线程安全问题。

        该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单线程调用时,在单线程时应尽量使用 StringBuilder ,而多线程时则使用StringBuffer。

StringStringBufferStringBuilder
是否可变不可变序列可变序列可变序列
效率较高最高
优点内存复用率高多线程安全单线程效率高

        内存服用率高:当我们创建多个内容相同的String对象时,系统只会在常量池中创建一个String对象,所以内存的复用率较高。

        效率不同:当我们对String对象进行增删改等操作时,系统实际上会创建一个新的新的字符串来存放处理后的String对象,原本的String对象会被抛弃,但仍留着内存之中,因此效率较低;而 StringBuilder 和 StringBuffer 可以直接对原对象进行修改,所以效率较高。

        线程安全:因为 StringBuffer 被 synchronized 关键字修饰,这意味着多个线程可以同时访问同一个 StringBuffer 对象而不会导致数据不一致的问题,而 StringBuilder 则可能会导致线程问题出现。

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值