【JAVA入门】Day22 - 包装类
【JAVA入门】Day22 - 包装类
文章目录
- 【JAVA入门】Day22 - 包装类
- 一、获取包装类里的对象
- 1.1 JDK5 之前的包装类
- 1.2 JDK5 之后的包装类
- 二、Integer里常用的成员方法
- 三、利用包装类写算法练习
包装类是 Java 中编写好的,基本数据类型对应的引用类型。
public class Test {public static void main(String[] args) {int i = 10;}
}
int 类型对应的包装类叫 Integer。
public class Integer {private int value;...构造方法......成员方法...
}
包装类的本质就是:用一个对象来存储基本类型。
在 Java 的许多方法中,参数都可以用 Object 类传递,但如果是基本数据类型就不能接收。
public void method(Object obj){...
}
而且,Java 的集合是不能存储基本数据类型的,只能存储用引用数据类型(包装类)。
在 Java 中,所有数据类型都有自己的包装类:
一、获取包装类里的对象
1.1 JDK5 之前的包装类
在 JDK5 以前,包装类的对象获取比较麻烦,用到下面的构造方法或 valueOf 方法。
public class IntegerDemo1 {public static void main(String[] args) {//1.利用构造方法获取Integer的对象(JDK5以前)Integer i1 = new Integer(1);Integer i2 = new Integer("1");System.out.println(i1);System.out.println(i2);//2.利用静态方法获取Integer的对象(JDK5以前的方式)Integer i3 = Integer.valueOf(123);Integer i4 = Integer.valueOf("123");Integer i5 = Integer.valueOf("123", 8); //八进制System.out.println(i3);System.out.println(i4);System.out.println(i5);}
}
要注意,这两种获取对象的方式在内存层面是有区别的。
首先,如果是 new 产生的 Integer 对象,一定是开辟了新的内存空间,所以它们之间比较的结果一定为 false。
但是,valueOf() 方法会对 -128 ~ 127 之间的数字(Byte的取值范围)进行优化,即缓存机制,如果已经生成了 -128 ~ 127 之间的 Integer 对象,再次创建在范围内的对象时,可以复用。因此下面例子中,i6 == i7 返回的结果为 true。
//3.这两种获取对象的区别Integer i6 = Integer.valueOf(127);Integer i7 = Integer.valueOf(127);System.out.println(i6 == i7); //trueInteger i8 = Integer.valueOf(128);Integer i9 = Integer.valueOf(128);System.out.println(i8 == i9); //falseInteger i10 = new Integer(127);Integer i11 = new Integer(127);System.out.println(i10 == i11); //falseInteger i12 = new Integer(128);Integer i13 = new Integer(128);System.out.println(i12 == i13); //false
在 JDK5 以前,包装类对象之间不能直接用基本的数学运算符号计算,我们需要先把包装类拆箱,用基本数据类型计算,然后再装箱。
public class IntegerDemo2 {public static void main(String[] args) {//在以前包装类如何进行计算Integer i1 = new Integer(1);Integer i2 = new Integer(2);//把两个数据进行相加//对象之间不能直接计算//1.把对象进行拆箱,变成基本数据类型//2.相加//3.装箱int result = i1.intValue() + i2.intValue();Integer i3 = new Integer(result);System.out.println(i3);}
}
1.2 JDK5 之后的包装类
JDK5 以后,我们有了改进的创建 Integer 对象的方式,即:自动拆箱和自动装箱。
- 自动装箱:基本数据类型会自动变成其对应的包装类。
- 自动拆箱:把包装类自动地变成其对应的基本数据类型。
public class IntegerDemo3 {public static void main(String[] args) {//自动拆箱Integer i1 = 10;//在底层,会自动调用静态方法valueOf()得到Integer对象//只不过这个动作不需要我们自己去操作了//自动拆箱Integer i2 = new Integer(10);int i = i2;//在JDK5以后,int和Integer可以看作是同一个东西了}
}
二者之间可以自动互转。
二、Integer里常用的成员方法
方法名 | 说明 |
---|---|
public static String toBinaryString(int i) | 得到二进制 |
public static String toOctalString(int i) | 得到八进制 |
public static String toHexString(int i) | 得到十六进制 |
public static int parseInt(String s) | 将字符串类型的整数转成int类型的整数 |
四个都是静态方法,可以直接用类名调用。
package Bag;public class IntegerDemo4 {public static void main(String[] args) {//1.把整数转为二进制,八进制,十六进制String str1 = Integer.toBinaryString(100);System.out.println(str1);String str2 = Integer.toOctalString(100);System.out.println(str2);String str3 = Integer.toHexString(100);System.out.println(str3);//2.将字符串类型的整数转成int类型的整数//Java 是强类型语言:每种数据都有自己的数据类型//计算的时候,如果不是同一种数据类型,是无法直接数学运算的int i = Integer.parseInt("123");System.out.println(i);System.out.println(i + 1);//细节1://在类型转换的时候,括号中的参数只能是数字的字符串,否则会报错//细节2://8种包装类中,除了Character,都有对应的parseXxx的方法,进行类型转换String str = "true";boolean b = Boolean.parseBoolean(str);System.out.println(b);}
}
学习完包装类字符串转数字,我们顺便学一下改进的键盘录入 nextLine(),之后键盘录入统一为这个方法。
package Bag;import java.util.Scanner;public class IntegerDemo5 {public static void main(String[] args) {//改写键盘录入代码//原键盘录入Scanner sc = new Scanner(System.in);System.out.println("请输入一个整数:");int i = sc.nextInt();System.out.println(i);System.out.println("请输入一个字符串:");String str = sc.next();System.out.println(str);//这种方法有弊端//当我们在使用next,nextInt,nextDouble在接收数据的时候,遇到空格,回车,制表符就停止了//键盘录入的是123 123,那么此时只能接收到空格前面的数据//因此我们统一使用nextLine()方法//它的特点是遇到回车才会停止录入System.out.println("请输入一个数字字符串:");String line = sc.nextLine();System.out.println(line);//转换为整数int j = Integer.parseInt(line);//转换为小数double d = Double.parseDouble(line);}
}
三、利用包装类写算法练习
【练习1】键盘录入:录入一些1~100之间的整数,添加到集合中,直到集合中所有数据和超过200为止。
package Bag;import java.util.ArrayList;
import java.util.Scanner;public class IntegerTest {public static void main(String[] args) {//键盘录入:录入一些1~100之间的整数//添加到集合中,直到集合中所有数据和超过200为止。//1.创建一个集合用来添加整数ArrayList<Integer> list = new ArrayList<>();//2.键盘录入数据添加到集合中,循环录入Scanner sc = new Scanner(System.in);while(true) {System.out.println("请输入一个整数:");String numStr = sc.nextLine();int num = Integer.parseInt(numStr);//先把异常数据过滤if(num < 1 || num > 100) {System.out.println("当前数字不在1~100范围中!请重新输入:");continue;}else{//num是基本数据类型int//在添加数据的时候触发了自动装箱//list.add(num.valueOf(num));list.add(num);}//统计集合中所有的数据和,判断是否大于200if(getSum(list)){System.out.println("当前数字和已超过200,输入结束!");break;}}//验证集合内容for(int i = 0; i < list.size(); i++) {if(i < list.size() - 1) {System.out.print(list.get(i) + ", ");}else{System.out.println(list.get(i));}}}private static boolean getSum(ArrayList<Integer> list) {int sum = 0;for(int i = 0; i < list.size(); i++) {sum = sum + list.get(i);}if(sum > 200) {return true;}else{return false;}}
}
【练习2】自己实现parseInt方法的效果,将字符串形式的数据转成整数。
要求:字符串只能是数字不能有其他字符,最少一位,最多10位,0不能作为开头。
package Bag;public class IntegerTest2 {public static void main(String[] args) {/*自己实现parseInt方法的效果,将字符串形式的数据转成整数。要求:字符串只能是数字不能有其他字符最少一位,最多10位,0不能作为开头。*///1.定义一个字符串String str = "123456789";//2.校验字符串//在开发中,我们习惯过滤异常数据,判断条件一般为取反if(!str.matches("[1-9]{1,10}")) {System.out.println("输入的字符串不符合要求!");}else{System.out.println("数据格式正确");//类型转换,把字符串变整数?//3.遍历字符串,得到里面的每一个字符//定义一个变量代表最终结果int number = 0;for(int i = 0; i < str.length(); i++) {char c = str.charAt(i);//'1' - '0' == 1int num = c - '0';//把每一位数字放到number当中number = number * 10 + num;}System.out.println(number);}}
}
【练习3】定义一个方法自己实现toBinaryString方法的效果,将一个十进制整数转成字符串表示的二进制。
除基取余法:不断地除以基数得到余数,直到商为0,再把余数倒着拼接起来即可。
package Bag;public class IntegerTest3 {public static void main(String[] args) {System.out.println(toBinaryString(100));}public static String toBinaryString(int number) {//不断去除以2,得到余数,直到商为0//定义一个StringBuilder用于拼接余数StringBuilder sb = new StringBuilder();while(true) {if(number == 0) {break;}//获取余数 %int remaindar = number % 2;//除以2number = number / 2;//倒着拼接,每次都要放到头部,所以用插入方法sb.insert(0,remaindar);}return sb.toString();}
}
【练习4】计算出生年月日到今日时间间隔为多少。
package Bag;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;public class IntegerTest4 {public static void main(String[] args) throws ParseException {//JDK7以前的方法//计算毫秒值//出生年月日String birthday = "2000年1月1日";SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");Date birthDate = sdf.parse(birthday);long birthDateTime = birthDate.getTime();//当前时间Date d = new Date();long nowTime = d.getTime();//计算时间差值long period = nowTime - birthDateTime;System.out.println(period);//将毫秒值转化为天数System.out.println(period / 1000 / 60 / 60 / 24);//JDK8以后的方法LocalDate ld1 = LocalDate.of(2000,1,1);LocalDate ld2 = LocalDate.now();long betweenDays = ChronoUnit.DAYS.between(ld1, ld2);System.out.println(betweenDays);}
}
【练习5】判断任意的一个年份是闰年还是平年。
package Bag;import java.time.LocalDate;
import java.util.Calendar;public class IntegerTest5 {public static void main(String[] args) {//判断任意一个年份是平年还是闰年//jdk7//获取2000年1月1日 0:0:0//获取2000年12月31日 23:59:59//判断间隔是否为366天//或者判断2月份天数//2000年2月1日 0:0:0//2000年3月1日 0:0:0//或利用Calendar类,把时间设置为2000年3月1日//往前减一天//看当前时间是28号还是29号Calendar c = Calendar.getInstance();//注意月份是0~11,3月是2c.set(2000, 2, 1);//再把日历往前减一天c.add(Calendar.DAY_OF_MONTH, -1);//查看当前时间int day = c.get(Calendar.DAY_OF_MONTH);if (day == 28) {System.out.println("是平年");} else {System.out.println("是闰年");}//JDK8//LocalDateLocalDate ld1 = LocalDate.of(2000, 3, 1);LocalDate ld2 = ld1.minusDays(1);//月份是1~12int dayOfMonth = ld2.getDayOfMonth();if(dayOfMonth == 28){System.out.println("是平年");}else{System.out.println("是闰年");}//LocalDate有专门的方法//是闰年返回trueSystem.out.println(ld1.isLeapYear());}
}