包装类&字符串类

包装类

含义:Java为纯面向对象语言(万物皆对象),而8种基本数据类型不能创建对象,破坏了Java纯面向对象的特征,所以Java给这8中基本数据类型分别匹配了对应的类,这些类叫做包装类/封装类

注意:每个基本数据类型都有一个与之匹配的类

继承关系:

基本数据类型引用数据类型继承关系
byteByteextends Number extends Object
shortShortextends Number extends Object
intIntegerextends Number extends Object
longLongextends Number extends Object
floatFloatextends Number extends Object
doubleDoubleextends Number extends Object
charCharacterextends Object
booleanBooleanextends Object

注意:

  1. 数值类型的包装类都继承Number
  2. int的包装类为 Integer
  3. char的包装类为 Character

装箱与拆箱

装箱

含义:将基本数据类型转换成包装类

    int i = 100;
    Integer integer = Integer.valueOf(i);//装箱
    System.out.println(integer);
拆箱

含义:包装类—>基本数据类型

    Integer integer = new Integer(100);
    int i = integer.intValue();//拆箱
    System.out.println(i);

JDK1.5的新特性:自动装箱、自动拆箱

自动装箱

含义:基本数据类型 —> 包装类

    int i = 100;
    Integer integer = i;//自动装箱(底层实现:Integer.valueOf(i);)
    System.out.println(integer);
自动拆箱

含义:包装类 —> 基本数据类型

    Integer integer = new Integer(100);
    int i = integer;//自动拆箱(底层实现:integer.intValue();)
    System.out.println(i);

应用场景

集合是类似数组的容器,但集合只能存储引用数据类型,如果想存储基本数据类型,就可以把基本数据类型转换为对应的包装类对象

实例应用

需求:把字符串数组{“1”,“2”,“3”,“4”,“5”}转换为int数组

	String[] ss = {"1","2","3","4","5"};
	
	int[] is = new int[ss.length];

	for (int i = 0; i < is.length; i++) {
        //1.将String转换为Integer对象
        //2.Integer对象自动拆箱成int数据
        int num = Integer.valueOf(ss[i]);

        is[i] = num;
    }
    for (int element : is) {
        System.out.println(element);
    }

深入包装类底层源码

 面试题:

    Integer integer1 = Integer.valueOf(100);
    Integer integer2 = Integer.valueOf(100);
    System.out.println(integer1 == integer2);//true
				

    Integer integer3 = Integer.valueOf(200);
    Integer integer4 = Integer.valueOf(200);
    System.out.println(integer3 == integer4);//false

总结:Integer底层有一个缓存类,缓存类中有一个数组,存储了-128~127Integer对象,Integer.valueOf(num)底层会判断num是否在-128~127这个区间,如果在就从缓存数组中获取数据,如果不在这个区间就重新new对象

字符串相关类

String类

注意:String是一个不可变的类,即一旦String对象被创建,这个对象中的字符序列是不可变的,直至该对象被销毁
String类的常用方法
public static void main(String[] args) {

    String str = "123abc";

    str = str.concat("DEF123");//在此字符串末尾追加字符串,并返回新的字符串
    str = str.substring(2);//从开始下标处截取到字符串末尾,并返回新的字符串
    str = str.substring(1, 7);//从开始下标处(包含)截取到结束下标处(不包含),并返回新的字符串
    str = str.toUpperCase();//转大写,并返回新的字符串
    str = str.toLowerCase();//转小写,并返回新的字符串

    str = "   123 a  bcD EF 123        ";

    str = str.trim();//去除首尾空格,并返回新的字符串 "123 a  bcD EF 123"
    str = str.replace('2', '-');//替换字符,并返回新的字符串
    str = str.replaceFirst("3", "小明");//替换第一个出现的字符串,并返回新的字符串
    str = str.replaceAll("1", "xxx");//替换字符串,并返回新的字符串
    str = str.replaceAll(" ", "");//替换字符串,并返回新的字符串(去掉字符串中所有的空格)

    System.out.println("判断两个字符串内容是否相同:(区分大小写)" + str.equals("xxx-小明abcDEFxxx-3"));
    System.out.println("判断两个字符串内容是否相同:(不区分大小写)" + str.equalsIgnoreCase("XXX-小明ABCdefxxx-3"));
    System.out.println("判断此字符串是否以某个字符串开头:" + str.startsWith("xxx"));
    System.out.println("判断此字符串是否以某个字符串结尾:" + str.endsWith("-3"));

    System.out.println("查询此字符串第一次在目标字符串中的下标:" + str.indexOf("-"));
    System.out.println("查询此字符串最后一次在目标字符串中的下标:" + str.lastIndexOf("-"));

    System.out.println("获取指定下标上的字符:" + str.charAt(4));

    //xxx-小明abcDEFxxx-3	
    System.out.println(str);

}
实例应用

练习:完成一个邮箱格式的校验
(1),“@”不能在第一位
(2),“.”不能在最后一位
(3),“@”和“.”中间应该有字符
(4), hhy@qq.com

public static void main(String[] args) {
		
		String email = "@hhyqq.com";
		
		int index1 = email.indexOf("@");
		int index2 = email.indexOf(".");
		
		if(index1 == 0 || index2 == email.length()-1 || (index2-index1)<=1){
			System.out.println("邮箱格式错误");
		}
		
	}
其他类型转字符串

直接使用 String.valueOf() 方法

    int i = 100;
    System.out.println(String.valueOf(i));

    boolean bool = true;
    System.out.println(String.valueOf(bool));
深入String创建对象问题

面试题1:下列代码创建几个String对象(考点:常量池中的值必须是唯一的)

​ String str1 = “abc”;
​ String str2 = “abc”;
​ 答案:一个
//str1存在栈中,字符串常量对象 abc 存在常量池中,str1指向常量abc,声明str2时,会先检查常量池中是否存在abc,如果存在就直接把该对象abc的地址赋给str2

面试题2:下列代码创建几个String对象(考点:常量池中的值必须是唯一的)
String str1 = new String(“abc”);
//2个。先创建字符串常量对象abc,再new对象,再把常量abc赋值给new出来的对象
String str2 = new String(“abc”);//因为常量池中已存在"abc",所以直接new对象,再赋值
答案:三个

public static void main(String[] args) {

    String str1 = "abc";
    String str2 = "abc";
    System.out.println(str1 == str2);//true.把字符串常量abc分别赋值给引用str1和str2

    //两个常量字符串直接在编译时拼接
    String str3 = "ab" + "c";	//等价于 String str3 = "abc";
    System.out.println(str3 == str1);//true

    //两个常量字符串直接在编译时拼接
    final String s1 = "ab";
    final String s2 = "c";
    String str4 = s1+s2;	//等价于 String str4 = "abc";
    System.out.println(str4 == str1);//true

    //两个变量字符串拼接底层是创建StringBuilder对象
    String s3 = "ab";
    String s4 = "c";
    String str5 = s3+s4;//(new StringBuilder(s3)).append(s4).toString()
    System.out.println(str5 == str1);//false
}

StringBuffer

  1. StringBuffer代表可变的字符序列,
    StringBuffer称为字符串缓冲区. 是线程安全的
  2. 它的工作原理是:
    1. 预先申请一块内存,存放字符序列 (底层是一个默认大小为16的字符数组)
    2. 如果字符序列满了,会重新改变缓存区的大小,以容纳更多的字符序列
    3. StringBuffer对象中的字符序列可变,这是与String最大的不同
public static void main(String[] args) {
    /**
	* 知识点:StringBuffer

	* 继承关系:StringBuffer extends AbstractStringBuilder
	*/

    //默认字符串缓冲区:16个字符
    //StringBuffer sb = new StringBuffer();

    //自定义字符串缓冲区:100个字符
    //StringBuffer sb = new StringBuffer(100);

    //自定义字符串缓冲区:"123abc".length() + 16 : 22个字符
    StringBuffer sb = new StringBuffer("123abc");

    sb.append("DEF123");//在末尾追加字符串
    sb.insert(6, "xxx");//在指定下标处插入字符串
    sb.setCharAt(3, 'A');//替换指定下标上的字符
    sb.replace(6, 9, "用良心做教育");//从开始下标处(包含)替换到结束下标处(不包含)的字符串

    sb.deleteCharAt(1);//删除指定下标上的字符
    sb.delete(5, 11);//从开始下标处(包含)删除到结束下标处(不包含)的字符串
    sb.reverse();//反转字符串

    //321FEDcbA31
    System.out.println(sb);
    
}

StringBuilder

使用上和StringBuffer一模一样,是线程不安全的

字符串频繁拼接问题

经验:频繁的拼接字符串请使用StringBuilder或StringBuffer

public static void main(String[] args) {

		//获取自1970.1.1 0:0:0到现在的毫秒数
		//long startTime = System.currentTimeMillis();
		//String str = "小明";
		//for (int i = 0; i < 50000; i++) {
		//str += "睡觉!";
    //底层实现	
    //str = str + "睡觉!"
    //str = new StringBuilder(str).append("睡觉!").toString();
		//}
		//long endTime = System.currentTimeMillis();
		//System.out.println("消耗时长:" + (endTime-startTime));//5746

		//获取自1970.1.1 0:0:0到现在的毫秒数
		long startTime = System.currentTimeMillis();
		StringBuilder sb = new StringBuilder("林成");
		for (int i = 0; i < 50000; i++) {
			sb.append("睡觉!");
			}
		long endTime = System.currentTimeMillis();
		System.out.println("消耗时长:" + (endTime-startTime));//5

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值