常用类库
泛型
概述:泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。(不确定类型的变量)
使用
泛型类
定义一个泛型类:
public class ClassName<T>{
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
泛型接口
public interface IntercaceName<T>{
T getData();
}
实现接口时,可以选择指定泛型类型,也可以选择不指定, 如下:
指定类型:
public class Interface1 implements IntercaceName<String> {
private String text;
@Override
public String getData() {
return text;
}
}
不指定类型:
public class Interface1<T> implements IntercaceName<T> {
private T data;
@Override
public T getData() {
return data;
}
}
泛型方法
private static <T> T 方法名(T a, T b) {}
泛型限制类型
1. 在使用泛型时, 可以指定泛型的限定区域 ,
- 例如: 必须是某某类的子类或 某某接口的实现类,格式:
<T extends 类或接口1 & 接口2>
泛型中的通配符 ?
类型通配符是使用?代替方法具体的类型实参。
1 <? extends Parent> 指定了泛型类型的上届
2 <? super Child> 指定了泛型类型的下届
3 <?> 指定了没有限制的泛型类型
作用
1、 提高代码复用率
2、 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
注意
在编译之后程序会采取去泛型化的措施。
也就是说Java中的泛型,只在编译阶段有效。
在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加
类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。
Math
//绝对值
System . out . println(Math. abs(-100));
System . out . println(Math . min(100 ,200));
System. out . println(Math . max(100,200));
//四舍五人
System . out . println(Math. round(100.5));
//注意是往前走
System. out . println(Math. round(-100.5));
//返回小于等于参数的最大整数 System. out . println(Math . floor(3.5)); System. out . println(Math. floor(-3.5)); //返回大于等于参数的最小整数 System . out. println(Math.ceil(3.5)); System . out . println(Math.ceil(-3.5));
Arrays
- 该类包含用于操作数组的各种方法(例如排序和搜索)。 此类还包含一个静态工厂,允许将数组视为列表。
如果指定的数组引用为null,则此类中的方法都抛出NullPointerException
,除非另有说明。
包含在此类的方法中的文件包括的实施方式的简要描述。 这些描述应被视为实施说明 ,而不是规范的一部分 。 只要遵守规范本身,实现者就可以随意替换其他算法。 (例如, sort(Object[])
使用的算法不一定是sort(Object[])
,但它必须是稳定的 。)
该班级是Java Collections Framework的成员。
int[] arr = {8,1,2,3,4,5,6,7}; System. out . println(arr) ; System. out . println( Arrays. toString(arr)); Arrays . sort(arr); System. out. println(Arrays.toString(arr));
//查找6在整个数组中的下标 System . out. println(Arrays.binarySearch(arr, 6));
//原先长度 System . out . println( arr . length); //扩充数组 arr = Arrays. copyOf(arr,15 ); //扩充后长度 System. out . println(arr . length);
1 BigDecimal类
概念
通过在控制台运行0.1+0.2, 会发现float和double的运算误差
由于float类型和doub1e类型在运算时可能会有误差,为了实现精确运算则需要借助java. math. BigDec ima1类加以描述
常用构造方法
public BigDecimal(String va1) {
}
常用方法
下述所有的运算方法,不会影响参与运算的数据本身,运算的结果会被封装为一个新的BigDecima1对象 ,这个对象会通过return返回出去
1.public BigDecimal add (BigDecimal augend); 加法运算
2.public BigDecinal subtract (BigDecinal augend); 减法运算
3.public BigDecimal multiply(BigDecimal augend); 乘法运算
4.public BigDecimal divide(BigDecimal augend); 除法运算
//精度高 BigDecimal b1 = new BigDecimal( "0.1"); BigDecimal b2 = new BigDecimal( "0.2"); //调用方法相加 BigDecimal b3 = b1.add(b2) ; b3.doubleValue(); System .out.println(b1); System.out.println(b2); System.out.println(b3);
Date
- Date类表示特定的时刻,精度为毫秒。
在JDK 1.1之前, Date类还有两个附加功能。 它允许将日期解释为年,月,日,小时,分钟和秒值。 它还允许格式化和解析日期字符串。 不幸的是,这些功能的API不适合国际化。 从JDK 1.1开始, Calendar类应该用于在日期和时间字段之间进行转换,而DateFormat类应该用于格式化和解析日期字符串。 不推荐使用Date中的相应方法。
Long getTime() 返回自此 Date
对象表示的1970年1月1日00:00:00 GMT以来的毫秒数。
Date(long date) | 分配 Date对象并初始化它以表示自标准基准时间(称为“纪元”)以来的指定毫秒数,即1970年1月1日00:00:00 GMT。
|
Date() | 分配 Date对象并对其进行初始化,使其表示分配时间,测量 Date到毫秒。 |
//创建一个当前时间的Date Date date = new Date(); //获取当前时间 System.out.println(date.toString()); //获取当前毫秒数 //System.out.println(date.getTime()); //减去一小时 long time = date . getTime()-(1*60*60*1000) ; Date date2 = new Date(time); System. out . println(date); System . out . println(date2);
DateFormat
是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化和分析日期或时间。
Calendar
//Calendar set get add //getTime 获取日历时间表示的Date对象 //getActualMaxmum 获取某字段的最大值 Calendar cl = Calendar. getInstance(); //更改时间 /*cl.set(Calendar.YEAR,2021); int year = cl. get (Calendar. YEAR); int day = cl. get(Calendar.DAY_OF_YEAR); System . out . println(year); System . out . println(day);*/ //机器里0-11 2020-12-12 加3 //cl.add( Calendar.MONTH,3); //减3 cl.add( Calendar.MONTH,-3); System. out . println( cl. get (Calendar .MONTH)); //获取日历时间表示的Date对象d //Date d = cl.getTime() //设置月份为2月份 cl.set(Calendar .MONTH,1); //通过月形式展示 int m = cl. getActualMaximum(Calendar.DAY_OF_MONTH); System . out. println(m);
System
- System类包含几个有用的类字段和方法。 它无法实例化。 System类提供的设施包括标准输入,标准输出和错误输出流; 访问外部定义的属性和环境变量; 加载文件和库的方法; 以及用于快速复制阵列的一部分的实用方法。
3.1、String 类(绝对重点)
之前的操作中,可以发现,使用String可以表示出一个字符串,但是使用此类的时候也会发现有一点的问题。
从String命名风格可以发现,String是- -个类,但是此类在使用的时候却发现可以不用构造方法而直接赋值,那么这样操作有那些特点呢?
String类表示字符串。Java程序中的所有字符串文字(例如"abc" )都实现为此类的实例(对象)。
字符串是不变的;它们的值在创建后无法更改。字符串缓冲区支持可变字符串。 因为String对象是不可变的, 所以可以共享它们。(若两个字符串完全相同,内存地址相同,有缓存,可以重复使用,但是如果是new开辟的空间内存地址一定不同)
例如
String str = "abc";
相当于:
char data[] = {"a', 'b', 'c'};
String str = new String(data) ;
字符量常量值
方法区(Method Area) ,又称永久代(Permanent Generation), 又称非堆区(Non-Heap space)方法区,又称永久代(Permanent Generation) ,常称为PermGen,位于非堆空间,又称非堆区(Non-Heapspace)。
方法区是被所有线程共享。
所有字段和方法字节码,以及- -些特殊方法如构造函数,接口代码也在此定义。
简单说,所有定义的方法的信息都保存在该区域,此区属于共享区间。
这些区域存储的是:静态变量+ 常量+类信息(构造方法/接口定义) +运行时常量池。
但是,实例变量 存在堆内存中,和方法区无关。
以上,只是逻辑上的定义。在HotSpot中,方法区仅仅只是逻辑上的独立,实际上还是包含在Java堆中,也是就说,方式区在物理上属于Java堆区中的一一部分,而永久区(Permanent Generation) 就是方法区的实现。
2、堆(heap)
一个JWM实例只存在一个堆内存堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行。
面试
新生代I( Young Generation, 常称为YoungGen)
老年代(01d Generation,常称为01dGen、Tenur ingGen)
永久代(Permanent Generation, 常称为PermGen)
2.1、新生区(New/Young Generation)
新生代(Young Generation) ,常称为YoungGen,位于堆空间;
新生区又分为Eden区和Survior (幸存区)。
Eden :新创建的对象
Survior 0、1:经过垃圾回收,但是垃圾回收次数小于15次的对象
2.2、养老代(o1d Generation)
老年代(01d Generation) ,常称为01dGen,位于堆空间;
o1d :垃圾回收次数超过15次,依然存活的对象
2.3、永久区(Permanent Generation)
永久代(Permanent Generation) ,常称为PermGen, 位于非堆空间。
JDK1.7之前:
运行时常量池(包含字符串常量池)存放在方法区,此时hotspot虚拟机对方法区的实现为永久代。
JDK1.7 :
字符串常量池被从方法区拿到了堆中;
运行时常量池剩下的东西还在方法区,也就是hotspot中的永久代。
JDK1.8 :
hotspot移除了永久代,用元空间(Metaspace)取而代之。这时候,
字符串常量池还在堆,
运行时常量池还在方法区,只不过方法区的实现从永久代变成元空间(Metaspace)。
拼接,产生垃圾(通过+拼接字符串能避免就避免)
可变字符序列
//StringBuilder线程不安全的实现 //StringBuffer线程安全的实现