Java学习笔记 - 4 Java核心类库

4 Java 核心类库

4.1 泛型

泛型,即“参数化类型”。就是将原来具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

作用:

  • 提高代码的复用率
  • 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
4.1.1 泛型类
public class ClassName<T> {
   
    private T data;
    
    public 	T getData() {
   
        return data;
    }
    
    public void setData() {
   
        this.data = data;
    }
}
4.1.2 泛型接口
public interface InterfaceName<T> {
   
    T getData();
}

// 实现接口时可以选择指定泛型类型,也可以不指定:

// 指定类型:
public class Interface1 implements InterfaceName<String> {
   
    private string text;
    @Override
    public String getData() {
   
        return text;
    }
}

// 不指定类型:
public class Interface2<T> implements InterfaceName<T> {
   
    private T data;
    @Override
    public T getData() {
   
        return data;
    }
}
4.1.3 泛型方法
private static <T> T methodName(T a, T b) {
   }

// e.g.
public static <T> void print(T a) {
   
    system.out.println(a);
}
4.1.4 泛型限制类型

指定泛型的限定区域,例如: 必须是某某类的子类或 某某接口的实现类:

// 格式:

// e.g.
public static void main(String[] args) {
   
    Plate<Apple> p = new Plate<>();
}
interface Fruit{
   }
class Apple implements Fruit{
   }
class Plate<T extends Fruit> {
   
    T data;
}
4.1.5 通配符 ?
  • 指定了泛型类型的上界

  • 指定了泛型类型的下界

  • 指定了没有限制的泛型类型

Plate<? extends Fruit> p = new Plate<Apple>(); // 上界
Plate<? super Apple> p = new Plate<Fruit>(); // 下界

注意:在编译之后程序会采取去泛型化的措施,也就是说Java中的泛型只在编译阶段有效,而不会进入到运行时阶段。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦除,并在对象进入和离开方法的边界处添加类型检查和类型转换的方法。


4.2 常见类库

4.2.1 java.util.Objects
  • 此类包含static实用程序方法(null或null防范,用于计算对象的哈希代码,返回对象的字符串,比较两个对象,检索索引或子范围值是否超出范围),用于操作对象或在操作前检查某些条件
  • 源码:
// static boolean equals(Object a, Object b)
public static boolean equals(Object a, Object b) {
   
    return (a == b) || (a != null && a.equals(b));
}

// static boolean isNull(Object obj)
public static boolean isNull(Object obj) {
    return obj == null; }

// static boolean nonNull(Object obj)
public static boolean isNull(Object obj) {
    return obj != null; }

// static boolean requireNonNull(T obj):检查对象引用是否不是null
public static <T> T requireNonNull(T obj) {
   
    if (obj == null)
        throw new NullPointerException(); //如果是空,直接抛出异常
    return obj;
}
4.2.2 java.lang.Math
//四舍五入
Math.round(-100.5); // -100
4.2.3 java.util.Arrays

binarySearch, compare, equals, sort, toString, copyOf

int[] arr = {2,3,4,5,1};
System.out.println(arr); //打印的是内存地址(哈希值)
System.out.println(Arrays.toString(arr)); //打印[2,3,4,5,1]
Arrays.sort(arr); //排序
Arrays.binarySearch(arr, 6); //二分查找
arr = Arrays.copyOf(arr, 15); //扩容至长度为15
4.2.4 java.math.BigDecimal

实现小数的精准运算

// 构造方法
public BigDecimal(String val) {
   }

// 常用方法
public BigDecimal add(BigDecimal augend);
public BigDecimal subtract(BigDecimal augend);
public BigDecimal multiply(BigDecimal augend);
public BigDecimal devide(BigDecimal augend);

// e.g.
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.2");
BigDecimal b3 = b1.add(b2); // 0.3
double d = b3.doubleValue(); // 转换为double类型
4.2.5 java.util.Date

表示特定的时刻,精度为毫秒

构造方法:

  • Date() 当前时间
  • Date(long date)

方法:

  • long getTime() 返回自1970年1月1日00:00:00GMT以来的毫秒数
  • void setTime(long time) 设置时间点
4.2.6 java.text.DateFormat
  • 用于格式化和解析日期字符串
  • 是一个抽象类,使用子类SimpleDateFormat
  • 常用方法:
    • String format(Date date) 格式化日期
    • Date parse(String source) 解析日期字符串
/**
 * y: 年
 * M: 月
 * d: 日
 * H: 时
 * m: 分
 * s: 秒
 */
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
String text = format.format(new Date()); // 将date对象格式化为字符串
Date date = format.parse("2021-12-12 12:12:12"); // 将符合格式的字符串转化为date对象,可用于计算时间差
4.2.7 java.util.Calendar
  • 是一个抽象类,通过其getInstance()方法创建对象
  • 年月日时分秒都存储在filed数组里,通过传入下标(例如Calendar.YEAR)用get()方法获取
  • 常用方法:
    • set get add
    • getTime 获取日历时间表示的Date对象
    • getActualMaximum 获取某字段的
Calendar cl = Calendar.getInstance(); //创建对象

int year = cl.get(Calendar.YEAR); //2020
int year = cl.get(Calendar.MONTH); //0-11
int day = cl.get(Calendar.DAY_OF_YEAR); //一年的第几天,从0开始

cl.set(Calendar.YEAR, 2021); //设置年为2021
cl.add(Calendar.YEAR, 1); //设置年+1

Date d = cl.getTime(); //获取日历时间表示的Date对象
int m = cl.getActualMaximum(Calendar.DAY_OF_MONTH); //当前月份的最大值
4.2.8 java.lang.System

常用方法:

  • gc() 运行垃圾回收器
  • exit(int status) 终止当前运行的Java虚拟机
  • static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 复制数组
4.2.9 java.lang.String
  • 字符串是不变的,他们的值在创建后无法更改

    String str = "abc";
    // 相当于
    char data[] = {
         'a', 'b', 'c'};
    string str = new String(data);
    
  • String类 用final修饰,不能被继承

  • 两个字符串内容如果完全相同,则它们采用同一块内存地址(即可共享);但如果 是通过new创建的对象,一定是新开辟的空间

  • 字符串常量池(存在方法区中)

    1. 方法区Method Area(加载代码的内存区),又称永久代Permanent Generation,被所有线程共享
    
    2. 堆heap
    1) 一个JVM实例只存在一个堆内存,大小是可以调节的;
    2) 类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行;
    3) 堆 在逻辑上分为三部分(Perm):
    - 新生代 YoungGen:存刚创建的对象,gc回收很快
    - 老年代 OldGen:存常用的对象(在新生代中连续15次没有被回收)
    - 永久代 PermGen:类、方法、常量、static修饰的(不会被垃圾回收)
    
    3. JDK1.8演变
    字符串常量池还在堆,运行时常量池还在方法区,只不过方法区的实现从永久代变成了元空间Metaspace;
    元空间与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中
    
  • 一种构造方法:

    String(byte[] bytes, Charset charset) 使用charset字符集解码字节数组

  • 方法:

    • int compareTo(String anotherString) 按字典顺序比较两个字符串
    • boolean contains(CharSequence s) 是否包含指定的char值序列
    • int indexOf(int ch) 指定字符第一次出现在字符串中的索引
    • String trim() 删除首尾空格
  • 字符串拼接:

    • 每+一次就在内存中创建一个新的String对象,即产生一次垃圾(在永久代里不会被回收)
    • 因此不应该使用String,应该使用StringBuffer / StringBuilder
    String, StringBuilder, StringBuffer 的区别:
        1. String 是字符串常量,不可变,修改时会创建了一个新的String对象,然后将指针指向它
        2. StringBuffer 和 StringBuilder 是字符串变量,使用时会对对象本身进行操作(会动态扩容),而不是生成新的对象再改变对象引用,最后可以用 toString()方法转成 String
        3. StringBuffer 是线程安全的;而 StringBuilder 不是(不能保证同步),速度更快,单线程时使用
        4. 在某些特别情况下, String 对象的字符串拼接其实被 Java Compiler 编译成了 StringBuffer 对象的拼接,所以这时 String 对象的速度不比 StringBuffer 对象慢,例如:
        
    	String s1 = "This is only a" + 

你可能感兴趣的:(Java,java)