包装类

针对八种基本数据类型相应的引用类型,有了类的特点,就能调用类中的方法。

基本数据类型 包装类
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double

装箱与拆箱

​ 这两个过程的主要用途在于使得在需要使用对象的场景中能够使用基本数据类型,以及在需要使用基本数据类型的场景中能够使用对象。例如,在集合类中,只能存储对象而不能存储基本数据类型,因此需要通过装箱将基本数据类型转换为对应的包装类对象。

​ 在jdk5之前,需要手动装箱与拆箱,jdk5及之后使用自动装箱与拆箱。

public class Test{
public static void main(String[] args){
int num = 100;
// 手动装箱
Integer i = new Integer(num);
Integer j = Integer.valueOf(num);
// 手动拆箱
int k = i.intValue();

// 自动装箱和拆箱
Integer a = num;
int b = a;
}
}

String

String类

  1. 字符串的字符使用Unicode字符编码,无论字母还是汉字都占2字节
  2. String类有很多构造器和构造器的重载,常用的有:

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);

  1. String类实现了接口Serializable(串行化:可以在网络传输)和接口Comparable(比较大小)
  2. String是final类,不能被继承
  3. String有属性private final char value[],用于存放字符串内容

常用方法

  1. equals:区分大小写,判断内容是否相等
  2. equalsIgnoreCase:忽略大小写,判断内容是否相等
  3. length:返回字符串长度
  4. substring:截取指定范围的子串,前闭后开区间
  5. trim:去掉前后空格
  6. charAt:获取索引处字符
  7. toUpperCase:把字符串全部转换成大写
  8. toLowerCase:把字符串全部转换成小写
  9. replace:str.replace(a,b)将str中所有的a替换成b
  10. split:字符串分割,类似于Python的split,需要用列表接收
  11. toCharArray:将字符串转化成字符数组char[]
  12. format:用法类似于c的printf
public class Test{
public String str;
public static void main(String[] args){
int a = 10;
String b = "bbb";
char c = 'c';
double d = 3.14159265;
String str = String.format("a=%d,b=%s,c=%c,d=%.2f", a, b, c, d);
}
}

StringBuffer类

​ StringBuffer是一个容器,因为是线程安全的(方法添加了synchronized修饰),所以一般用于多线程,代表可变的字符序列,可以对字符串内容进行增删,方法与String大体相同。

构造器

StringBuffer():构造一个不带字符的缓冲区,大小为16

StringBuffer(int capacity):构造一个不带字符,容量为capacity的缓冲区

StringBuffer(String str):构造一个内容为str,大小为str.length()+16的缓冲区

转换机制

// String -> StringBuffer
String s1 = "hello";
StringBuffer sb = new StringBuffer(s1);

// StringBuffer -> String
String s2 = sb.toString();

常用方法

  1. append:向后面添加字符串
  2. delete:delete(a,b)删除指定范围的字符,左闭右开,即删除[a,b)内的字符
  3. replace:replace(a,b)用法同delete,删除改为替换
  4. indexOf:查找指定子串在字符串中第一次出现的位置,没找到返回-1
  5. insert:insert(a,b)在a位置插入字符串b

StringBulider类

​ StringBulider和StringBuffer类均代表可变的字符序列,但是StringBulider效率更高,两者方法相同,所以使用和StringBuffer一样,但是StringBulider一般用于单线程。

效率:StringBulider > StringBuffer > String

Math类

包含用于执行基本数学运算的方法。

  1. abs:绝对值
  2. pow:幂运算,pow(a,b)指求a的b次方
  3. ceil:向上取整
  4. floor:向下取整
  5. sqrt:开方
  6. random:返回一个[0,1)之间的double类型的随机数
  7. max/min:求最值

Arrays类

Arrays用于管理或操作数组。

  1. toString:将数组内容变成字符串,便于输出查看内容
  2. sort:将数组排序,可以使用匿名内部类改变排序方法
  3. binarySearch:通过二分查找有序数组的某一个数,如果存在返回索引。不存在返回-(本应该在的位置+1)
  4. fill:fill(arr, num)将arr数组内容全部变成num
  5. asList:将一组值转换成list

大数处理方案

BigInteger适合保存超出long表示范围的整数。BigDecimal适合保存超出double表示范围的浮点型。

加减乘除不能使用正常的数学符号,必须使用类给定的方法。

用法(以BigInteger为例,BigDecimal与之相同)

public class Test{
public static void main(String[] args){
BigInteger num1 = new BigInteger("9999999999999999999999999999999999");
BigInteger num2 = new BigInteger("100");
BigInteger add = num1.add(num2);
BigInteger sub = num1.subtract(num2);
BigInteger mul = num1.multiply(num2);
BigInteger div = num1.divide(num2);

// 注意,BigDecimal的除法可能与BigInteger不同
BigDecimal num3 = new BigDecimal("10.999999999999999999999999999999999991");
BigDecimal num4 = new BigDecimal("3");
// 如果除数除不尽的话会报异常,解决办法:
BigDecimal div2 = num3.divide(num4, BigDecimal.ROUND_CEILING); // 保留与被除数相同的精度
}
}

日期类

第一代日期类

用于获得系统时间。

  1. Date:new Date()获取当前系统时间。
  2. SimpleDateFormat:将日期转换成指定格式的字符串SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E")E表示星期

第二代日期类

指Calendar类,Calendar是一个抽象类,构造器使用private修饰。可以通过getInstance()获取实例。Calendar没有专门的格式化方法,需要自己组合显示。

  1. Calendar c = Calendar.getInstance()创建日历类对象,包含Calendar字段
  2. 获取日历:

c.get(Calendar.YEAR)

c.get(Calendar.MONTH) + 1 // 月默认从0开始

c.get(Calendar.DAY_OF_MONTH)

c.get(Calendar.HOUR)

c.get(Calendar.MINUTE)

c.get(Calendar.SECOND)

第三代日期类

为了改善前两代日期类的不足,在jdk8中推出了第三代日期类

  1. LocalDate:年月日
  2. LocalTime:时分秒
  3. LocalDateTime:日期+时间

LocalDateTime ldt = LoaclDateTime.now()

ldt.getYear()

ldt.getMonthValue()

ldt.getDayOfMonth()

ldt.getHour()

ldt.getMinute()

ldt.getSecond()

  1. SimpleDateFormat:格式日期类
LocalDateTime ldt = LoaclDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH小时mm分钟ss秒");
String format = dtf.format();
  1. plus系列方法:plusDayplusMinutes等方法,可以查看多少天/分钟后的日期是什么
  2. minus系列方法:可以查看给定时间之前的日期是什么

泛型

​ 泛型是一种在设计和使用类、接口和方法时,允许更广泛地操作各种数据类型的机制。泛型提供了一种在代码中使用一般类型而不是具体类型的方式,在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值类型、参数类型,这样可以提高代码的重用性、可读性和类型安全性,使用任何字母都可以,通常使用<E><T><K>表示。Java的源码中使用了大量泛型以提高代码复用性。

语法

public class Main{
public static void main(String[] args){
Test<Integer> test = new Test<>(1); // 使用Integer代替E
System.out.println(test.function()); // 返回1
}
}
// 自定义泛型
class Test<T>{
T s;

public Test(T s){
this.s = s;
}

public T function(){
return s;
}
// 泛型方法
public <T, R> void method(T t, R r){
return null;
}
// ......
}

注意事项

  1. 给泛型指定数据类型时,只能使用引用类型,不能是基本数据类型
  2. 在给泛型指定具体类型时,可以传入该类型或者该类型的子类型
  3. 使用泛型的数组不能初始化(因为不知道这里要用什么样的类型,不知道要开多大空间)
  4. 静态属性和静态方法中不能使用泛型(因为静态是和类相关的,在类加载时,对象还没有创建,如果静态属性和静态方法使用了泛型,JVM就无法完成初始化)
  5. 泛型方法可以在普通类中,也可以在泛型类中
  6. 如果创建类时没有指定类型,默认为Object
  7. 若在接口类中使用泛型,类型在继承接口或者实现接口时确定
interface IUsb<U, R>{
int n = 10;
R get(U u);
void f(R r);
default R method(U u){
return null;
}
}

interface IA extends IUsb<String, Double> {......}

class AA implements IUsb<String, Double> {......}
  1. 泛型的通配符:
    • <?>代表支持任意泛型类型
    • <? extends A>代表支持A类以及A的子类,规定了泛型类型的上限
    • <? super A>代表支持A类以及A的父类,规定了泛型类型的下限