包装类 Wrapper
包装类的分类
针对八种基本数据类型相应的引用类型 ——包装类
有了类的特点,就可以调用类中的方法
boolean
Boolean
char
Character
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
前两种包装类,实现 Comparable 和
Serializable 接口
后六种包装类的父类为 Number, 这些包装类自身实现
Comparable 接口, Number 实现
Serializable 接口
包装类和基本数据类型的转换
jdk5前的手动装箱和拆箱方式,装箱:基本类型 \(\rightarrow\) 包装类型,反之,拆箱
jdk5以后(含jdk5)的自动装箱和拆箱方式
自动装箱底层调用的是 valueOf 方法,比如
Integer.valueOf()
1 2 3 4 5 6 7 8 9 10 int n1 = 100 ;Integer integer = new Integer (n1); Integer integer1 = Integer.valueOf(n1); int n = integer.intValue(); int n2 = 200 ;Integer integer2 = n2;int n = integer2;
exercise
1 2 Object obj1 = true ? new Integer (1 ) : new Double (2.0 ); System.out.println(obj1);
三元运算符看作一个整体,提升精度
包装类型和 String
类型的相互转换
以 Integer 和 String 转换为例,其它类似
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Integer i = 10 ;String s1 = i.toString();String s2 = String.valueOf(i);String s3 = i + "" ;Integer j = new Integer (s1);Integer j2 = Integer.valueOf(s2); Integer.toString(int i); String.valueOf(int i); i + "" ;
Integer 类和 Character
类的常用方法
1 2 3 4 5 6 7 8 9 10 11 12 Integer.MIN_VALUE Integer.MAX_VALUE Character.isDigit('a' ) Character.isLetter('a' ) Character.isUpperCase('a' ); Character.isLowerCase('a' ); Character.isWhitespace('a' ); Character.toUpperCase('a' ) Character.toLowerCase('A' )
exercise
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public void method () { Integer i = new Integer (1 ); Integer j = new Integer (1 ); System.out.println(i == j); Integer m = 1 ; Integer n = 1 ; System.out.println(m == n); Integer x = 128 ; Integer y = 128 ; System.out.println(x == y); }public static Integer valueOf (int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer (i); }
1 2 3 4 5 6 7 8 Integer x = 127 ;int y = 127 ; System.out.println(x == y); Integer m = 128 ;int n = 128 ; System.out.println(m == n);
String 类
1 2 3 4 5 6 7 8 9 10 11 public final class String implements java .io.Serializable, Comparable<String>, CharSequence, Constable, ConstantDesc { @Stable private final byte [] value; }
String 类的理解和创建对象
String 对象用于保存字符串,也就是一组字符序列;
字符串常量对象是用双引号括起的字符序列,例如:"你好"、"12.97"、"girl";
字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节;
String 类较常用构造器:
1 2 3 4 5 String s1 = new String ();String s2 = new String (String original);String s3 = new String (char [] a);String s4 = new String (char [] a, int startIndex, int count);String s5 = new String (byte [] b);
String 类实现了Serializable接口,和Comparable接口,
作用见上边注释;
String 是 final
类,不能被其他的类继承
String 有属性 private final byte[] value;
用于存放字符串内容(jdk8及以前是char),value 是一个
final
类型,地址 不可修改,即value不可指向新的地址,但是单个字符内容是可以修改的。
创建 String 对象的两种方式
1 2 3 4 5 String s = "hello" ;String s = new String ("hello" );
两种创建 String 对象的区别:
方法一:先从常量池查看是否有"hello"数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向常量池的空间地址;
方式二:先从堆中创建空间,里面维护了value属性,指向常量池的"hello"空间。如果常量池没有"hello",重新创建,如果有,直接通过value指向。s最终指向的是堆中的空间地址;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 String a = "abc" ;String b = "abc" ; System.out.println(a.equals(b)); System.out.println(a == b); String a = new String ("abc" );String b = new String ("abc" ); System.out.println(a.equals(b)); System.out.println(a == b); String a = "xyz" ;String b = new String ("xyz" ); System.out.println(a == "xyz" ); System.out.println(a == b.intern()); System.out.println(b == b.intern());
当调用intern方法时,如果池已经包含一个等于此
String 对象的字符串 (用 equals(Object)
方法确定),则返回池中的字符串。否则,将此 String
对象添加到池中,并返回此 String 对象的引用。 ####
exercise
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Animal { String name; public Animal (String name) { this .name = name; } }String s1 = "java" ; Animal a = new Animal (s1); Animal b = new Animal (s1); System.out.println(a == b); System.out.println(a.equals(b)); System.out.println(a.name == b.name); String s4 = new String ("java" ); String s5 = "java" ; System.out.println(s1 == s4); System.out.println(s4 == s5); String t1 = "hello" + s1; String t2 = "hellojava" ; System.out.println(t1.intern() == t2);
字符串对象的特性
String 是一个 final
类,代表不可变的字符序列
字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。
exercise
1)以下语句创建了几个对象?
1 2 3 String s1 = "hello" ; s1 = "hhh" ;
2)
1 2 3 String a = "hello" + "abc" ;
3)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 String a = "hello" ; String b = "abc" ; String c = a + b; String d = "hello" + "abc" ; System.out.println(c == d);
4)
1 2 3 4 5 6 String s1 = "hello" ;String s2 = "world" ;String s3 = "helloworld" ;String s4 = (s1 + s2).intern(); System.out.println(s3 == s4); System.out.println(s3.equals(s4));
5)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Test1 { String str = new String ("hello" ); final char [] ch = {'j' , 'a' , 'v' , 'a' }; public void change (String str, char ch[]) { str = "java" ; ch[0 ] = 'h' ; } public static void main (String[] args) { Test1 ex = new Test1 (); ex.change(ex.str, ex.ch); System.out.print(ex.str + " and " ); System.out.println(ex.ch); } }
String 类的常见方法
String
类是保存字符串常量的。每次更新都需要重新开辟空间,效率较低,因此Java设计者还提供了
StringBuilder 和 StringBuffer 来增强
String 的功能,并且提高效率。
1 2 3 4 String s = new String ("" );for (int i = 0 ; i < 80000 ; i ++ ) { s += "hello" ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 equals equalsIgnoreCase length indexOf lastIndexOf substring trim charAt toUpperCase toLowerCase concat replace split compareTo toCharArray format
exercise 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package com.company.string_;public class StringExercise { public static void main (String[] args) { String str = "abcdef" ; try { str = reverse(str, 0 , 5 ); } catch (RuntimeException e) { System.out.println(e.getMessage()); return ; } System.out.println("交换后: " + str); } public static String reverse (String str, int start, int end) { if (!(str != null && start >= 0 && end < str.length() && start < end)) { throw new RuntimeException ("参数不正确" ); } char [] chars = str.toCharArray(); char tmp; for (int i = start, j = end; i < j; i++, j--) { tmp = chars[i]; chars[i] = chars[j]; chars[j] = tmp; } return new String (chars); } }
exercise 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package com.company.string_;public class StringExercise02 { public static void main (String[] args) { String name = "kuhn" ; String pwd = "123445" ; String email = "c_kudos@163.com" ; try { userRegister(name, pwd, email); System.out.println("正常运行..." ); } catch (Exception e) { System.out.println(e.getMessage()); } } public static void userRegister (String name, String pwd, String email) { if (!(name != null && pwd != null && email != null )) { throw new RuntimeException ("参数不能为空" ); } int len = name.length(); if (!(len >= 2 && len <= 4 )) { throw new RuntimeException ("用户名长度2~4" ); } if (!(pwd.length() >= 6 && isDigital(pwd))) { throw new RuntimeException ("密码长度大于等于6,且全为数字" ); } int idx1 = email.indexOf('@' ); int idx2 = email.indexOf('.' ); if (!(idx1 > 0 && idx2 > idx1)) { throw new RuntimeException ("邮箱不合规范" ); } } public static boolean isDigital (String str) { char [] chars = str.toCharArray(); for (char aChar : chars) { if (aChar < '0' || aChar > '9' ) return false ; } return true ; } }
StringBuffer 类
java.lang.StringBuffer
代表可变的字符序列,可以对字符串内容进行增删;很多方法与
String 相同,但 StringBuffer 是可变长度的;
StringBuffer 是一个容器。
在父类中, AbstractStringBuilder 有属性
byte[] value,不是 final,该
value 数组存放字符内容,存放在堆中而非常量池中。
StringBuffer 是一个 final
类,不能被继承。
String VS StringBuffer
String 保存的是字符串常量,里面的值不能更改,每次
String 类的更新实际上就是更改地址,效率较低
private final byte value[];
StringBuffer
保存的是字符串变量,里面的值可以更改,每次
StringBuffer的更新实际上可以更新内容,不用每次更新地址 ,效率较高
byte[] value; //这个放在堆中
StringBuffer 的构造器
1 2 3 4 5 6 7 8 StringBuffer() StringBuffer(CharSequence seq) StringBuffer(int capacity) StringBuffer(String str)
String 和 StringBuffer
相互转换
1 2 3 4 5 6 7 8 9 10 11 12 13 String s = "hello" ;StringBuffer b1 = new StringBuffer (s);StringBuffer b2 = new StringBuffer (); b2.append(s);String s2 = b1.toString(); String s3 = new String (b1);
StringBuffer 类的常见方法
1 2 3 4 5 6 1. 增 append2. 删 delete (start , end )3. 改 replace (start , end , string )4. 查 indexOf5. 插 insert6. 获取长度 length ()
Exercise
1 2 3 4 5 6 7 8 9 String str = null ;StringBuffer sb = new StringBuffer (); sb.append(str); System.out.println(sb.length()); System.out.println(sb); StringBuffer sb1 = new StringBuffer (str); System.out.println(sb1);
1 2 3 4 5 6 String price = "8123456.59" ;StringBuffer sb = new StringBuffer (price);for (int i = sb.LastIndexOf("." ) - 3 ; i > 0 ; i -= 3 ) { sb = sb.insert(i, "," ); } System.out.println(sb);
StringBuilder 类
一个可变的字符序列。此类提供一个与StringBuffer
兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作
StringBuffer
的一个简易替换,用在字符串缓冲区被单个线程 使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比
StringBuffer 要快。
在 StringBuilder 上的主要操作是 append 和
insert 方法,可重载这些方法,以接受任意类型的数据。
串行化(对象可以网络传输,也可以保存到文件)
StringBuilder 是 final
类,不能被继承
StringBuilder 对象字符序列仍然存放在其父类
AbstractStringBuilder的 byte[] value;
因此字符序列是在堆中
StringBuilder 的方法没有做互斥处理,即没有
synchronized 关键字
String、StringBuffer
和 StringBuilder 的比较
StringBuilder 和 StringBuffer
非常类似,均代表可变的字符序列,而且方法也一样
String:不可变字符序列,效率低,但是复用率高
StringBuffer:可变字符序列、效率较高(增删)、线程安全
StringBuilder:可变字符序列、效率最高、线程不安全
String使用注意说明:
1 2 3 4 5 6 String s = "a" ; s += "b" ;
使用的原则,结论:
如果字符串存在大量的修改操作,一般使用 StringBuffer 或
StringBuilder
如果字符串存在大量的修改操作,并在单线程的情况,使用
StringBuilder
如果字符串存在大量的修改操作,并在多线程的情况,使用StringBuffer
如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等
Math 类
Math
类包含用于执行基本数学运算的方法,如初等指数,对数,平方根和三角函数。都是静态方法
1 2 3 4 5 6 7 8 9 abs pow ceil floor round sqrt random max min
Arrays 类
Arrays
里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 1. toString 返回数组的字符串形式 Integer[] arr = {1 , 2 , 3 }; Arrays.toString(arr) 2. sort 排序 (自然排序和定制排序) Integer arr[] = {1 , -1 , 7 , 0 , 89 }; Arrays.sort(arr); Arrays.sort(arr, new Comparator () { @Override public int compare (Object o1, Object o2) { Integer i1 = (Integer) o1; Integer i2 = (Integer) o2; return i2 - i1; } });3. binarySearch 通过二分搜索法进行查, 要求必须排好序 int index = Arrays.binarySearch(arr, 3 ); 4. copyOf 数组元素的复制 Integer[] newArr = Arrays.copyOf(arr, arr.length);5. fill 数组元素的填充 Integer[] num = new Integer []{9 , 3 , 2 }; Arrays.fill(num, 99 );6. equals 比较两个数组元素内容是否完全一致 boolean equals = Arrays.equals(arr, arr2);7. asList 将一组值,转换成list集合 List<Integer> asList = Arrays.asList(2 , 3 , 4 , 5 , 6 , 1 ); System.out.println("asList = " + asList); System.out.println("运行类型:" , + asList.getClass());
模拟排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package com.company.arrays_;import java.util.Arrays;import java.util.Comparator;public class ArraysSortCustom { public static void main (String[] args) { int [] arr = {81 , -1 , 3 , -5 , 25 }; bubble02(arr, new Comparator () { @Override public int compare (Object o1, Object o2) { int i1 = (Integer) o1; int i2 = (Integer) o2; return i2 - i1; } }); System.out.println(Arrays.toString(arr)); } public static void bubble (int [] arr) { for (int i = 0 ; i < arr.length; i++) { for (int j = 0 ; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1 ]) { int tmp = arr[j]; arr[j] = arr[j + 1 ]; arr[j + 1 ] = tmp; } } } } public static void bubble02 (int [] arr, Comparator c) { for (int i = 0 ; i < arr.length; i++) { for (int j = 0 ; j < arr.length - 1 - i; j++) { if (c.compare(arr[j], arr[j + 1 ]) > 0 ) { int tmp = arr[j]; arr[j] = arr[j + 1 ]; arr[j + 1 ] = tmp; } } } } }
System
1 2 3 4 5 6 7 8 1 . exit 退出当前程序 exit (0 ) 表示退出状态2 . arraycopy:复制数组元素,比较适合底层调用,一般使用Array.copyOf完成复制数组 int[] src = {1 ,2 ,3 }; int[] dest = new int[3 ]; // dest 当前是 {0 , 0 , 0 } System.arraycopy(src, 0 , dest, 0 , 3 ); // 3 表示length3 . currentTimeMillens: 返回当前时间距离 1970 -1 -1 的毫秒数4 . gc: 运行垃圾回收机制 System.gc();
BigInteger、BigDecimal
1 2 3 4 5 6 7 8 9 - 应用场景1. BigInteger 适合保存比较大的整数2. BigDecimal 适合保存精读更高的浮点数- 常见方法1. add 加2. subtract 减3. multiply 乘4. divide 除 // bigDecimal.divide(x, BigDecimal.ROUND_CELING); 指定精度,以防抛出异常
日期类
第一代日期类
Date 精确到毫秒,表示特定的瞬间
SimpleDateFormat 格式和解析日期的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package com.company.date_;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class Date01 { public static void main (String[] args) throws ParseException { Date d1 = new Date (); System.out.println("当前日期: " + d1); Date d2 = new Date (9234567 ); System.out.println(d1.getTime()); SimpleDateFormat sdf = new SimpleDateFormat ("yyyy年MM月dd日 hh:mm:ss E" ); String format = sdf.format(d1); System.out.println(format); String s = "1996年01月01日 10:20:30 星期一" ; Date parse = sdf.parse(s); System.out.println(parse); } }
第二代日期类
Calendar 类(日历)
Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR,
MONTH, DAY_OF_MONTH, HOUR
等日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法
1 2 public abstract class Calendar implements Serializable , Cloneable, Comparable<Calendar> {...}
1 2 3 4 5 6 7 8 Calendar c = Calendar.getInstance(); System.out.println(c); System.out.println(c.get(Calendar.YEAR)); System.out.println(c.get(Calendar.MONTH) + 1 ); System.out.println(c.get(Calendar.DAY_OF_MONTH)); System.out.println(c.get(Calendar.HOUR)); System.out.println(c.get(Calendar.MINUTE)); System.out.println(c.get(Calendar.SECOND));
第三代日期类
前面两代日期类的不足分析 JDK
1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK
1.1引入Calendar类之后被弃用了。
而Calendar也存在问题是:
可变性:像日期和时间这样的类应该是不可变的。
偏移性:Date中的年份是从1900开始的,而月份都从0开始。3)格式化:格式化只对Date有用,Calendar则不行。
此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)。
LocalDate(日期)、LocalTime
(时间)、LocalDateTime (日期时间) jdk8加入
1 2 3 4 5 6 7 8 LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); ldt.getYear(); ldt.getMonthValue(); ldt.getDayOfMonth(); ldt.getHour(); ldt.getMinute(); ldt.getSecond();
DateTimeFormatter 格式日期类
1 2 3 DateTimeFormat dtf = DateTimeFormatter.ofPattern(格式); String str = dtf.format(日期对象);
Instant 时间戳
1 2 3 4 5 6 7 Instant now = Instant.now(); System.out.println(now);Date date = Date.from(now);Instant instant = date.toInstant();
第三代日期类更多方法
1 2 3 4 5 6 LocalLocalDateTime类 MonthDay类: 检查重复事件 是否是闰年 增加日期的某个部分 使用plus 方法测试增加时间的某个部分 使用minus 方法测试查看一年前和一年后的日期