Day 07包装类和String用法

文章详细介绍了Java中的包装类,包括它们与基本数据类型之间的转换,如parseInt和valueOf方法。还讨论了String的不可变性,字符串的创建、比较和拼接操作,以及内存中的表现。此外,提到了StringBuffer和StringBuilder在多线程和性能上的差异。
摘要由CSDN通过智能技术生成

包装类

包装类的基本使用

Java提供了8中数据类型对应的包装类

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

包装类与基本数据类型的互相转换

在这里插入图片描述

public class Demo01 {
    //TODO string转其他基本数据类型---->pasexxxx()方法
    public static void main(String[] args) {
        String str1 = "123";

        int num = Integer.parseInt(str1);
        System.out.println(num);

        String str2 = "true";
        boolean b = Boolean.parseBoolean(str2);
        System.out.println(b);
    }
}
public class Demo02 {
    //TODO 基本数据类型----->String,调用string重载的valueOf()
    public static void main(String[] args) {
        int num1 = 10;

        String str1 = num1 + "";

        float f1 = 31.4f;
        String str2 = String.valueOf(f1);
        System.out.println(str2);

        Double d1 = new Double(3);
        String str3 = String.valueOf(d1);
        System.out.println(str3 );
    }
}

//TODO 自动装箱与自动拆箱
public static void main(String[] args) {
        //自动装箱: 基本数据类型 ---》包装类
        int num1 = 10;
        Integer inte1 = num1; //自动装箱
        System.out.println(inte1);

        boolean b1 = true;
        Boolean b2 = b1; //自动装箱
        System.out.println(b2);

        //包装类 --》String
        Integer inte2 = 11;
        String s = inte2.toString();
        System.out.println(s);

        //自动拆箱: 包装类----》基本数据类型
        int num3 = inte1;
        System.out.println(num3);
    }
//TODO 包装类---》基本数据类型  :调用包装类的方法:xxxValue()
public static void main(String[] args) {
        Integer int1 = new Integer(12);
        int i1 = int1.intValue();

        System.out.println(i1 + 1);

        Float f1 = new Float(31.4);
        float f2 = f1.floatValue();
        System.out.println(f2 + 1);
    }
    //TODO 基本数据类型 ---》 包装类,调用包装类的构造器
    public static void main(String[] args) {
        int num1 = 10;

        Integer int1 = new Integer(num1);
        System.out.println(int1);

        Float f1 = new Float(12.3f);
        System.out.println(f1);

        Boolean b = new Boolean(true);
        System.out.println(b);
    }
public static void main(String[] args) {

        //包装类--》String
        int num1 = 10;
        Integer int1 = new Integer(num1);
        String str1 = int1.toString();//拆箱返回的是字符串
        System.out.println(str1);

        Float f1 = new Float(12.3f);
        String str2 = f1.toString();
        System.out.println(str2);

        Boolean b = new Boolean(true);
        String str3 = b.toString();
        System.out.println(str3);


        //String ---->包装类
        Boolean aTrue = new Boolean("true");
    }

装箱与拆箱

基本数据类型的包装类是为了基本数据类型转为对象提供的,那么对于基本数据类型和包装类之间有处理关系:

  • 数据装箱:基本数据类型------->包装类,一般利用构造方法
  • 数据拆箱:从包装类------->基本数据类型 调用xxxValue()
public static void main(String[] args) {

        Integer obj1 = new Integer(10);//装箱
        int num1 = obj1.intValue();//拆箱
        System.out.println(num1);

        //自动装箱与拆箱
        Integer obj2 = 10; //自动装箱
        int num = obj2; //自动拆箱
        obj2++;
        System.out.println(num * obj2);

        // Object 接收 基本数据类型
        Object obj3 = 19.3;//double 自动转型为 Double,向上转型为Object
        double num3 = (Double) obj3;
        System.out.println(num3);
    }

对于包装类的判断上:

public class Demo02 {
    public static void main(String[] args) {
        Integer x1 = 99;
        Integer y1 = 99;
        System.out.println(x1 == y1);

        Integer x2 = 127;
        Integer y2 = 99;
        System.out.println(x2 == y2);

        Integer x3 = -129;
        Integer y3 = -129;
        System.out.println(x3 == y3);//flase,因为超过了范围,所以new 了新的对象
        System.out.println(x3.equals(y3));//true
        // 因为包装类重写了equals()方法,调用了xxxvalue()方法,进行了拆箱,最终是这是两个基本数据类型的比较(看源码)

        Integer x4 = 127;
        Integer y4 = new Integer(127);
        System.out.println(x4 == y4); //false
        System.out.println(x4.equals(y4)); //true
    
        int x5 = 99;
        Integer y5 = 99;
        System.out.println(x5 == y5);


        int x6 = 128;
        Integer y6 = 128;
        System.out.println(x6 == y6);
    } 

在这里插入图片描述

String类

字符串相关的类

字符串

  1. 字符串,使用“ ”引用起来
  2. String声明为final,不可以被继承
  3. String实现了serializable接口,表示字符串是支持序列化
  4. String实现了comparable接口:表示可以比较大小
  5. String内部定义了final char【】value 用于存储字符串数据

String类不可变性

  1. String: 代表不可变的字符串序列,简称不可变性

体现:

a.当对字符串重新赋值时,需要重写指定内存区赋值,不能使用原有的value进行赋值

b.对现有的字符串进行连接操作时,也需要重新制定内存区域赋值,不能使用原有的value赋值

c.当调用String的replace()方法修改字符或者字符,也需要重新指定内存区域赋值,不能使用原有的value进行赋值

public class StringTest {
    public static void main(String[] args) {
        String str1 = "abc";
        String str2 = "abc";

        str1 = "hello";
        System.out.println(str1==str2);//比较的是地址值
        System.out.println(str1);
        System.out.println(str2);

        System.out.println("=================");
        String str3 = "abc";
        str3 += "def";
        System.out.println(str3);
        System.out.println("=================");

        String str4 = "abc";
        String str5 = str4.replace('a','e');
        System.out.println(str4);//abc
        System.out.println(str5);//ebc
        
    }
}

在这里插入图片描述

在这里插入图片描述

String不同实例化方式的对比

String 对象的创建
String str1 = "hello";

//this.value = new char[0]
String str2 = new String();

//this.value = original.value;
String str3 = new String(String original);

//this.value = Arrays.copyOf(value, value.length);
String str4 = new String(char value[]);

String str4 = new String(char value[],int startIndex, int count);
String str1 = “abc”; 与 String str2 = new String(“abc”);的区别
  • 字符串常量存储在字符串常量池里面,目的是共享
  • 字符串对象存储在堆中

在这里插入图片描述

String的实例化方式

方式一: 通过字面量定义的方式

方式二: 通过 构造器的方式

public static void main(String[] args) {
        //通过字面量的方式定义,存储在 字符串常量池里面
        String str1 = "eagel";
        String str2 = "eagel";

        //通过构造器的方式:存储在堆里面
        String str3 = new String("eagel");
        String str4 = new String("eagel");

        System.out.println(str1 == str2);
        System.out.println(str1 == str3);
        System.out.println(str1 == str4);
        System.out.println(str3 == str4);

    }
public static void main(String[] args) {
        //通过字面量的方式定义,存储在 字符串常量池里面
        String str1 = "eagel";
        String str2 = "eagel";

        //通过构造器的方式:存储在堆里面
        String str3 = new String("eagel");
        String str4 = new String("eagel");

        System.out.println(str1 == str2);
        System.out.println(str1 == str3);
        System.out.println(str1 == str4);
        System.out.println(str3 == str4);

        System.out.println("=======================");

        Person person1 = new Person("herb", 18);
        Person person2 = new Person("herb", 18);

           System.out.println(person1.name.equals(person2.name));
        //true
        System.out.println(person1.name == person2.name);
        //true

        person2.name = "eagle";
        System.out.println(person2.name);
    }

在这里插入图片描述

面试题:通过String str1 = new String(“herb”);方式 创建对象,请问在内存中创建了多少个对象?

两个:一个是堆空间中对象,另一个是char[]数组

String 不同的拼接操作对比

  1. 常量与常量的拼接结果在常量池,且常量池中不会存在相同的内容
  2. 只要其中一个是变量,结果就在堆中
  3. 如果拼接的结果调用intern()方法,返回值就在常量池中。
public class Demo02 {
    public static void main(String[] args) {
        String str1 = "JavaEE";
        String str2 = "eagle";

        String str3 = "JavaEEeagle";
        String str4 = "JavaEE" + "eagle";
        String str5 = str1 + "eagle";
        String str6 = "JavaEE" + str2;
        String str7 = str1 + str2;

        System.out.println(str3 == str4);//true
        System.out.println(str3 == str5);//false
        System.out.println(str3 == str6);//false
        System.out.println(str5 == str6);//false
        System.out.println(str3 == str7); //false
        System.out.println(str5 == str7);//false
        System.out.println(str6 == str7);//false
    }
}
  public static void main(String[] args) {
        String str1 = "JavaEE";
        String str2 = "eagle";
        String str3 = str2 + "eagle";//结果在堆中

        System.out.println(str1 == str3); //false

        final String str4 = "JavaEE";
        String str5 = str4 + "eagle";
        System.out.println(str1 == str4);//true
    }
陷阱
  1. String str1 = “a” 在常量池

  2. str1 = str1 + “b”

    说明,实际上原来的 "a"字符串对象已经丢弃,现在在对空间产生了一个字符串 str1 + “b”,如果多次执行这些改变字符串内容的操作,会导致大量副本字符串对象存留在内存中。

  3. String str2 = “ab” 在常量池

  4. String str3 = “a” + “b” 在常量池(指向str2)

  5. String str4 = str1.intern(); //引用str2 (字符串常量池)

说明:堆空间的str1 对象在调用 intern()之后,会将常量池中已经存在的 "ab"字符串赋值给 str4

public class Demo04 {

    public void change(String str1, char chats[]) {
        str1= "hello";
        chats[0] = 'a';
    }

    public static void main(String[] args) {
        String str = new String("herb");
        char[] chars = {'e', 'a', 'g', 'l', 'e'};

        Demo04 test = new Demo04();

        test.change(str, chars);

        System.out.println(str); //字符串的不可变性
        System.out.println(chars);
    }
}

在这里插入图片描述

String常用方法

  1. int length() :返回字符串的长度

  2. char charAt(int index):返回某索引处的字符

  3. boolean isEmpty():判断字符串是否为空

  4. String toLowerCase():将String 中的所有字符转换为小写

  5. String toUpperCase() : 将String中的所有字符转换为大写

  6. String trim():返回字符串的副本,忽略 前面的空白和尾部的空白

  7. boolean equals(Object anObject):比较字符串的内容是否相等

  8. boolean equalsIgnoreCase(String anotherString):比较字符串的内容是否相等,忽略大小写

  9. String concat(String str):将字符串拼接到此字符串的结尾,等价与”+“

  10. int compareTo(String anotherString):比较两个字符串的大小

  11. String substring(int beginIndex):返回一个新的字符串,字符串从beginIndex开始截取到最后一个字符

  12. String substring(int beginIndex, int endIndex):返回一个新的字符串,字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串

public static void main(String[] args) {
        String str1 = "helloworld";
        System.out.println(str1.length());
        System.out.println(str1.charAt(0));
        System.out.println(str1.charAt(3));
        System.out.println(str1.isEmpty());

        String str2 = str1.toUpperCase();
        System.out.println(str1);
        System.out.println(str2);

        String str3 = "      herb  eag  le   ";
        String str4 = str3.trim();
        System.out.println(str3);
        System.out.println(str4);
    }
public static void main(String[] args) {
        String str1 = "HELLOWORLD";
        String str2 = "helloworld";
        System.out.println(str1.equals(str2));//false
        System.out.println(str1.equalsIgnoreCase(str2));//true


        String str3 = "aaa";
        String str4 = str3.concat("herb");
        System.out.println(str4);

        String str5 = "aaa";
        String str6 = new String("bbb");
        System.out.println(str5.compareTo(str6));//-1


        String str7 = "你好呀,herb";
        String str8 = str7.substring(2);
        System.out.println(str7);
        System.out.println(str8);


        String str9 = str7.substring(2, 4);
        //[2,4)-->【2,3】
        System.out.println(str9);

    }
  1. boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
  2. boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
  3. boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
  4. boolean contains(CharSequence s):判断字符串是否包含指定的字符穿
  5. int indexOf(String str):返回指定字符串在此字符串中第一次出现的所用
  6. int indexOf(String str, int fromIndex):从指定的索引开始,返回指定字符串在此字符串中第一次出现的索引。
  7. int lastIndexOf(String str):返回指定字符串在此字符串中最右边出现的索引(最后一次出现)
  8. int lastIndexOf(String str, int fromIndex):从指定的索引反向搜索,返回指定字符串最后一次出现处的索引

indexOf 和 lastIndexOf 方法如果找不到,返回-1

public static void main(String[] args) {
String str1 = “helloworld”;
boolean rld = str1.endsWith(“rld”);
System.out.println(rld);

    boolean hel = str1.startsWith("hel");
    System.out.println(hel);

    boolean ll = str1.startsWith("ll", 2);
    System.out.println(ll);

    System.out.println(str1.contains("wor"));

    System.out.println(str1.indexOf("ll"));

    System.out.println(str1.indexOf("ll",4));

    System.out.println(str1.lastIndexOf("rl"));
    System.out.println(str1.lastIndexOf("ll", 4));
}

替换:

  1. String replace(char oldChar, char newChar):返回一个新的字符串,它是通过 newChar 替换 字符串中所有的oldChar
  2. String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换此字符串所有匹配字面值目标序列的子字符串
  3. String replaceAll(String regex, String replacement):使用给定 replacement 替换此字符串所有满足正则表达式的子字符串。
  4. String replaceFirst(String regex, String replacement):使用 replacement 替换此字符串满足正则表达式的第一个子字符串。

匹配:

boolean matches(String regex):字符串是否 匹配 给定的正则表达式

  1. String[] split(String regex):根据给定的正则表达式 的匹配 来拆分字符串
  2. String[] split(String regex, int limit):根据给定的正则表达式 来拆分字符串,但是最多不超过limit个,如果超过了,剩下的全都放到最后一个元素中。
public static void main(String[] args) {
        String str1 = "herb  eagle";
        String replace = str1.replace('h', 'a');
        System.out.println(replace);

        String replace1 = str1.replace("erb", "avc");
        System.out.println(replace1);
    }

String与char[]之间的转换

String —>char[]:调用 String 的 toCharArray()

char[]—>String : 调用String的构造器

public static void main(String[] args) {
        String str1 = "123abc";
        char[] chars = str1.toCharArray();

        for (int i = 0; i < str1.length(); i++) {
            System.out.print(chars[i]);
        }
        System.out.println();
        char[] chars1 = {'h', 'e', 'r', 'b', 'e', 'a','g', 'l', 'e'};
        String s = new String(chars1);
        System.out.println(s);
    }

String与byte[]之间的转换

String —>byte[]:调用 String的 getBytes()

byte[]----> String:调用String的构造器

编码: 字符串—>字节(二进制)

解码:字节(二进制)—>字符串

public static void main(String[] args) throws UnsupportedEncodingException {
        String str1 = "aa123你好";
        byte[] bytes = str1.getBytes();
        System.out.println(Arrays.toString(bytes));
        byte[] bytes1 = str1.getBytes("gbk");
        System.out.println(Arrays.toString(bytes1));

        String str2 = new String(bytes);
        System.out.println(str2);

        String str3 = new String(bytes1);//出现乱码
        System.out.println(str3);//编码集和解码集不一致!

        String gbk = new String(bytes1, "gbk");
        System.out.println(gbk);
    }

String 算法

  1. 模拟一个 trim方法,去除字符串两端的空格
public class MyTrimTest {

    public static String MyTrim(String str) {
        if (str != null) {
            int start = 0;//头指针
            int end = str.length() - 1;//尾指针

            while ((start < end) && (str.charAt(start) == ' ')) {
                start++;
            }

            while ((start < end) && (str.charAt(end) == ' ')) {
                end--;
            }

            return str.substring(start, end + 1);
        }
        return null;
    }

    public static void main(String[] args) {
        String str = "   abc   ";
        String s = MyTrim(str);
        System.out.println(s);
    }
}

反转字符串,指定部分反转

abcde —> edcba

public class ReverseTest {

    //TODO char[] 数组
    public static String reverse(String str, int startIndex, int endIndex) {
        if (str != null && str.length() != 0) {
            char[] chars = str.toCharArray();
            for (int i = startIndex, j = endIndex; i < j; i++, j--) {
                char temp = chars[i];
                chars[i] = chars[j];
                chars[j] = temp;
            }
            return new String(chars);
        }
        return null;
    }


    public static String reverse2(String str, int startIndex, int endIndex) {
        if (str != null && str.length() != 0) {
           String reverStr = str.substring(0, startIndex);
           System.out.println(reverStr);//ab

            for (int i = endIndex; i >=startIndex ; i--) {
                reverStr += str.charAt(i);
            }
            reverStr += str.substring(endIndex + 1);
            return reverStr;
        }
        return null;
    }
    
    public static void main(String[] args) {
        String str = "abcdefg";
        String reverse = reverse2(str, 2, 5);
        System.out.println(reverse);
    }
}

StringBuffer 和 StringBuilder

String、StringBuffer、StringBuilder 的区别

String:不可变的字符串,底层用char[]存储

StringBuffer:可变的字符串,线程安全,效率低,底层用char[]存储

StringBuilder :可变的字符串,线程不安全,效率高,底层用char[]存储

public static void main(String[] args) {
        StringBuffer abc = new StringBuffer("abc");
        abc.setCharAt(0, 'm');
        System.out.println(abc);

        StringBuffer stringBuffer = new StringBuffer();
        System.out.println(stringBuffer.length());
    }

常用方法

  1. StringBuffer append(xxx): 字符拼接
  2. StringBuffer delete(int start, int end):删除指定位置的内容
  3. StringBuffer insert(int offset, xxx):在指定位置插入 xxx
  4. StringBuffer reverse() :字符串反转
  5. int indexOf(String str):
  6. String substring(int start, int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串
  7. int length()
  8. char charAt(int index)
  9. void setCharAt(int index, char ch):修改指定位置的字符
public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("abcdef");
        stringBuffer.append(1);
        stringBuffer.append('1');
        System.out.println(stringBuffer);

        /*stringBuffer.delete(2,4);
        System.out.println(stringBuffer);*/

        stringBuffer.replace(2,4,"herb");
        System.out.println(stringBuffer);

        stringBuffer.insert(2, "eagle");
        System.out.println(stringBuffer);
        stringBuffer.reverse();
        System.out.println(stringBuffer);

        String substring = stringBuffer.substring(1, 5);
        System.out.println(substring);
    }

String、StringBuffer,StringBuilder效率对比

StringBuilder > StringBuffer > String

public static void main(String[] args) {
        long startTime = 0;
        long endTime = 0;
        StringBuffer stringBuffer = new StringBuffer("");
        StringBuilder stringBuilder = new StringBuilder("");

        startTime = System.currentTimeMillis();

        for (int i = 0; i < 500000; i++) {
            stringBuffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();

        System.out.println(endTime - startTime);


        startTime = System.currentTimeMillis();

        for (int i = 0; i < 500000; i++) {
            stringBuilder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println(endTime - startTime);
    }
public static void main(String[] args) {
        long startTime = 0;
        long endTime = 0;
        StringBuffer stringBuffer = new StringBuffer("");
        StringBuilder stringBuilder = new StringBuilder("");

        startTime = System.currentTimeMillis();

        for (int i = 0; i < 500000; i++) {
            stringBuffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();

        System.out.println(endTime - startTime);


        startTime = System.currentTimeMillis();

        for (int i = 0; i < 500000; i++) {
            stringBuilder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println(endTime - startTime);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值