JavaSE学习笔记(十四)—— 基本类型包装类
一、基本类型包装类介绍
Java有8种基本类型byte,int,long,double,float,boolean,char,short,它们只能做赋值、运算、取值等简单操作,相对其进行复杂操作就不方便了。例如:通过文本框获得用户输入的数字数据,因为文本框里面是书写文本数据的,所以后台得到的都是字符串。如果想要对字符串中的数字进行运算,必须将字符串转换成数字。
怎么解决上述出现的问题呢?
为了对基本数据类型进行更多的操作,更方便的操作,Java就针对每一种基本数据类型值封装成了对象,8种基本数据类型封装后的对象称为包装类。将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。
二、基本类型和对象类型
基本类型与对象类型最大的不同点在于,基本类型基于数值,对象类型基于引用。
基本类型的变量在栈的局部变量表中直接存储的具体数值,而对象类型的变量则存储的是堆中的引用。
显然,相对于基本类型的变量来说,对象类型的变量需要占用更多的内存空间。
上面说到,基本类型基于数值,所以基本类型是没有类而言的,是不存在类的概念的,也就是说,变量只能存储数值,而不具备操作数据的方法。对象类型则截然不同,变量实际上是某个类的实例,可以拥有属性方法等信息,不再单一的存储数值,可以提供各种各样对数值的操作方法,但代价就是牺牲一些性能并占用更多的内存空间。
之所以 Java 里没有一刀切了基本类型,就是看在基本类型占用内存空间相对较小,在计算上具有高于对象类型的性能优势,当然缺点也是不言而喻的。
所以一般都是结合两者在不同的场合下适时切换,那么 Java 中提供了哪些「包装类型」来弥补「基本类型」不具备面向对象思想的劣势呢?
可以看到,除了 int 和 char 两者的包装类名变化有些大以外,其余六种基本类型对应的包装类名,都是大写了首字母而已。
注意,所有的包装类都是final修饰的,也就是它们都是无法被继承和重写的。
下面重点介绍Integer类和Character类,其它类型都是相似的。
三、Integer类
Integer 类在对象中包装了一个基本类型 int 的值。该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。
3.1 构造方法
- public Integer(int value)
- public Integer(String s) 注意:这个字符串必须是由数字字符组成
public class IntegerDemo { public static void main(String[] args) { // 方式1 int i = 100; Integer ii = new Integer(i); System.out.println("ii:" + ii); // 方式2 String s = "100"; // NumberFormatException // String s = "abc"; Integer iii = new Integer(s); System.out.println("iii:" + iii); } }
3.2 int类型和String类型的相互转换
int类型转成String类型:String.valueOf(number)
// int -- String int number = 100; // 方式1 String s1 = "" + number; System.out.println("s1:" + s1); // 方式2(推荐) String s2 = String.valueOf(number); System.out.println("s2:" + s2); // 方式3 // int -- Integer -- String Integer i = new Integer(number); String s3 = i.toString(); System.out.println("s3:" + s3); // 方式4 // public static String toString(int i) String s4 = Integer.toString(number); System.out.println("s4:" + s4);
String类型转成int类型:Integer.parseInt(s)
// String -- int String s = "100"; // String -- Integer -- int Integer ii = new Integer(s); // public int intValue() int x = ii.intValue(); System.out.println("x:" + x); //方式2(推荐) //public static int parseInt(String s) int y = Integer.parseInt(s); System.out.println("y:"+y);
3.3 常用的基本进制转换
【十进制到二进制,八进制,十六进制】
- public static String toBinaryString(int i)
- public static String toOctalString(int i)
- public static String toHexString(int i)
// 十进制到二进制,八进制,十六进制 System.out.println(Integer.toBinaryString(100)); System.out.println(Integer.toOctalString(100)); System.out.println(Integer.toHexString(100)); System.out.println("-------------------------");
【十进制到其他进制】
public static String toString(int i,int radix):返回用第二个参数指定基数表示的第一个参数的字符串表示形式。
// 十进制到其他进制 System.out.println(Integer.toString(100, 10)); System.out.println(Integer.toString(100, 2)); System.out.println(Integer.toString(100, 8)); System.out.println(Integer.toString(100, 16)); System.out.println(Integer.toString(100, 5)); System.out.println(Integer.toString(100, 7)); System.out.println(Integer.toString(100, -7)); System.out.println(Integer.toString(100, 70)); System.out.println(Integer.toString(100, 1)); System.out.println(Integer.toString(100, 17)); System.out.println(Integer.toString(100, 32)); System.out.println(Integer.toString(100, 37)); System.out.println(Integer.toString(100, 36)); System.out.println("-------------------------");
由这个我们也看到了进制的范围:2-36
为什么呢?0,...9,a...z
【其他进制到十进制】
public static int parseInt(String s,int radix):使用第二个参数指定的基数,将字符串参数解析为有符号的整数。
//其他进制到十进制 System.out.println(Integer.parseInt("100", 10)); System.out.println(Integer.parseInt("100", 2)); System.out.println(Integer.parseInt("100", 8)); System.out.println(Integer.parseInt("100", 16)); System.out.println(Integer.parseInt("100", 23));
3.4 自动装、拆箱
JDK5的新特性
自动装箱:把基本类型转换为包装类类型
自动拆箱:把包装类类型转换为基本类型
public class IntegerDemo { public static void main(String[] args) { // 定义了一个int类型的包装类类型变量i // Integer i = new Integer(100); Integer ii = 100; ii += 200; System.out.println("ii:" + ii); // 通过反编译后的代码 // Integer ii = Integer.valueOf(100); //自动装箱 // ii = Integer.valueOf(ii.intValue() + 200); //自动拆箱,再自动装箱 // System.out.println((new StringBuilder("ii:")).append(ii).toString()); } }
注意:在使用时,Integer x = null;上面的代码就会出现NullPointerException。
3.5 缓冲池
public class IntegerDemo { public static void main(String[] args) { Integer i1 = new Integer(127); Integer i2 = new Integer(127); System.out.println(i1 == i2);//false System.out.println(i1.equals(i2));//true System.out.println("-----------"); Integer i3 = new Integer(128); Integer i4 = new Integer(128); System.out.println(i3 == i4);//false System.out.println(i3.equals(i4));//true System.out.println("-----------"); Integer i5 = 128; Integer i6 = 128; System.out.println(i5 == i6); System.out.println(i5.equals(i6));//false System.out.println("-----------");//true Integer i7 = 127; Integer i8 = 127; System.out.println(i7 == i8);//true System.out.println(i7.equals(i8));//true // 通过查看valueOf()的源码,我们就知道了,针对-128到127之间的数据,做了一个数据缓冲池,如果数据是该范围内的,每次并不创建新的空间 // Integer ii = Integer.valueOf(127); } }
注意:Integer的数据直接赋值,如果在-128到127之间,会直接从缓冲池里获取数据
四、Character类
Character 类在对象中包装一个基本类型 char 的值。此外,该类提供了几种方法,以确定字符的类别(小写字母,数字,等等),并将字符从大写转换成小写,反之亦然
4.1 构造方法
Character(char value)
public class CharacterDemo { public static void main(String[] args) { // 创建对象 // Character ch = new Character((char) 97); Character ch = new Character('a'); System.out.println("ch:" + ch); } }
4.2 成员方法
- public static boolean isUpperCase(char ch):判断给定的字符是否是大写字符
- public static boolean isLowerCase(char ch):判断给定的字符是否是小写字符
- public static boolean isDigit(char ch):判断给定的字符是否是数字字符
- public static char toUpperCase(char ch):把给定的字符转换为大写字符
- public static char toLowerCase(char ch):把给定的字符转换为小写字符
public class CharacterDemo { public static void main(String[] args) { // public static boolean isUpperCase(char ch):判断给定的字符是否是大写字符 System.out.println("isUpperCase:" + Character.isUpperCase('A')); System.out.println("isUpperCase:" + Character.isUpperCase('a')); System.out.println("isUpperCase:" + Character.isUpperCase('0')); System.out.println("-----------------------------------------"); // public static boolean isLowerCase(char ch):判断给定的字符是否是小写字符 System.out.println("isLowerCase:" + Character.isLowerCase('A')); System.out.println("isLowerCase:" + Character.isLowerCase('a')); System.out.println("isLowerCase:" + Character.isLowerCase('0')); System.out.println("-----------------------------------------"); // public static boolean isDigit(char ch):判断给定的字符是否是数字字符 System.out.println("isDigit:" + Character.isDigit('A')); System.out.println("isDigit:" + Character.isDigit('a')); System.out.println("isDigit:" + Character.isDigit('0')); System.out.println("-----------------------------------------"); // public static char toUpperCase(char ch):把给定的字符转换为大写字符 System.out.println("toUpperCase:" + Character.toUpperCase('A')); System.out.println("toUpperCase:" + Character.toUpperCase('a')); System.out.println("-----------------------------------------"); // public static char toLowerCase(char ch):把给定的字符转换为小写字符 System.out.println("toLowerCase:" + Character.toLowerCase('A')); System.out.println("toLowerCase:" + Character.toLowerCase('a')); } }
【练习】
统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
/* * 分析: * A:定义三个统计变量。 * int bigCont=0; * int smalCount=0; * int numberCount=0; * B:键盘录入一个字符串。 * C:把字符串转换为字符数组。 * D:遍历字符数组获取到每一个字符 * E:判断该字符是 * 大写 bigCount++; * 小写 smalCount++; * 数字 numberCount++; * F:输出结果即可 */ public class CharacterTest { public static void main(String[] args) { // 定义三个统计变量。 int bigCount = 0; int smallCount = 0; int numberCount = 0; // 键盘录入一个字符串。 Scanner sc = new Scanner(System.in); System.out.println("请输入一个字符串:"); String line = sc.nextLine(); // 把字符串转换为字符数组。 char[] chs = line.toCharArray(); // 遍历字符数组获取到每一个字符 for (int x = 0; x < chs.length; x++) { char ch = chs[x]; // 判断该字符 if (Character.isUpperCase(ch)) { bigCount++; } else if (Character.isLowerCase(ch)) { smallCount++; } else if (Character.isDigit(ch)) { numberCount++; } } // 输出结果即可 System.out.println("大写字母:" + bigCount + "个"); System.out.println("小写字母:" + smallCount + "个"); System.out.println("数字字符:" + numberCount + "个"); } }