常用类库
我们先进性一些泛型的了解,学会泛型的基本使用方法
泛型
概述
泛型的本质是参数化类型,指的就是所操作的数据类型被指定为一个参数(在未操作时类型是未给定的,在使用/调用时传入具体的类型)。这种方法可以使用在类、接口和方法的创建当中。
使用方式
泛型类
定义一个泛型类的格式:
public class 类名<T>{
private T 属性名;
public T get属性名(){
return 属性名;
}
public void set属性名(T 属性名){
this.属性名 = 属性名;
}
怎么设置需要获(set)什么类型的数据呢?看下面 声明对象 的代码演示
类名<数据类型1> 对象名 = new 类名<数据类型1>();
在JDK1.7之和可以这样写(省略掉后一个类名里面的数据类型1):
类名<数据类型1> 对象名 = new 类名<>();
还可以在创建类的时候创建多个泛型类,如下所示
public class 类名<T1,T2,T3,...>{}
使用的方法也是一样的,下面就来看一看示例程序
package com.test.genericity;
/**
* 泛型再在类里面使用
* 定义一个泛型A,后续会输入相应的类型
*/
//多指定泛型也是ok的,使用逗号隔开
public class Preson<A,B,C> {
private int age;
private String name;
//泛型
private A date;
//为了演示可同时使用多个泛型,不在进行展开
//private B date2;
//private C date3;
//快捷键生成所有属性的getter/setter方法
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public A getDate() {
return date;
}
public void setDate(A date) {
this.date = date;
}
//快捷键生成toString()方法
@Override
public String toString() {
return "Preson{" +
"age=" + age +
", name='" + name + '\'' +
", date=" + date +
'}';
}
}
还有一段程序:
package com.test.genericity;
public class Demo1 {
public static void main(String[] args) {
//格式注意,在类后面加上<类型>,jdk1.7之前后面的类也得加上<类型>
Preson<String> p = new Preson<>();
//调用该方法输入的类型就是由泛型在上面创建对象的时候指定的
p.setDate("a");
//泛型在方法当中的使用
print(123);
}
}
泛型接口
定义一个泛型接口的格式:
public interface IntercaceName<T>{
T getData();
}
实现接口泛型时,可以选择指定泛型类型,也可以选择不指定,如下例程序
-
指定类型
public class Interface implements InterfaceA<String> { //接口指定为String类型,下面都得是String类型 private String text; @Override public String getData() { return text; } }
-
不指定类型
public class Interface<T> implements InterfaceB<T> { //接口泛型未指定,所以下面的类型都得是未指定的 private T data; @Override public T getData() { return data; } }
泛型方法
private static <T> T 方法名(T a, T b) {}
举一个例子
package com.test.genericity;
public class Demo1 {
public static void main(String[] args) {
//泛型在方法当中的使用,以下示例就能打印除输入的123
print(123);
}
/**
* 泛型在方法当中的使用
* @param a
* @param <T>
*/
public static <T> void print(T a){
//类型未被指定,可以输入String,integer...类型,后顺利打印
System.out.println(a);
}
}
泛型限制类型
当我们需要指定一个泛型的限定区域时,就可以使用该方法
//格式:
<T extends 类或接口1 & 接口2>
示例:
package com.test.genericity;
/**
* 在使用泛型时,可以指定泛型的限定区域
* 泛型限制类型的例子
*/
public class Demo2 {
public static void main(String[] args) {
//指定了只能是Fruit类,而Apple就是Fruit类的子类
Plate<Apple> p = new Plate<>();
}
}
//定义一个接口
interface Fruit{}
class Apple implements Fruit{}
//extends在这里指的是只能是Fruit类,区域性限制的一个操作
class Plate<T extends Fruit>{
T date;
}
泛型中的通配符 ? 的使用
格式:
- <? extends Parent> - - 指定了泛型类型的上届
- <? super Child> - - 指定了泛型类型的下届
- <?> - - 指定了没有限制的泛型类型
示例:
package com.test.genericity;
/**
* 在使用泛型时,可以指定泛型的限定区域
* 泛型限制类型的例子
*/
public class Demo3 {
public static void main(String[] args) {
//上届限定的使用,上届限定为Furits.?必须是Fruits的子或Fruits子的子
//Plates<? extends Fruits> p = new Plates<Apples>();
//下届限定的使用,下届限定为Apple.?必须是Apple的父或Apple父的父
Plates<? super Apple> p = new Plates<Object>();
/**
* <?>--可以当成Object来看待(可以被设置为任何数据类型),但是使用的时候只能传递指定的类型(指定 * 以后只能接受指定的类型数)
*/
}
}
//定义一个接口
interface Fruits{}
class Apples implements Fruits{}
//extends在这里指的是只能是Fruit类,区域性限制的一个操作
class Plates<T>{
T date;
}
注:在编译之后程序会采取去泛型化的措施,就是说在编译之后程序会把程序员指定的类型替换掉泛型化的类型;也就是说Java中的泛型,只在编译阶段有效。所以泛型信息不会进入到运行时阶段
java.util.Objects类
简介
java.util.Objects类是属于java.lang.Object的子类。
API Note:
静态方法如checkIndex (int, int) ,checkFromToIndex(int, int, int) ,和checkFromIndexSize (int, int, int) 提供用于如果对应于索引和子范围的值超出边界的检查的便利性。这些静态方法的变体支持定义运行时异常以及相应的异常详细消息,这些消息在值超出范围时抛出。此类方法接受功能接口参数,即BiFunction实例, 它将超出范围的值映射到运行时异常。将这 些方法与作为lambda表达式,方法引用或捕获值的类的参数结合使用时应小心。在这种情况 下,与功能接口分配相关的捕获成本可能超过检查边界的成本。
举例使用Objects.equal()方法
以下代码使用了Objects类当中的方法:
- equals
涉及到的知识点面试点:
- 使用Objects.equals的时候,无论参数是否为空都可以调用执行
- 当两参都为null,调用Objects.equals仍然可以得出true
注:使用Objects.equal()时别忘记了导包(java.util.Objects)
我们先创建一个Preson类:
package com.test.genericity;
public class Preson {
private int age;
private String name;
//快捷键生成所有属性的getter/setter方法
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
调用Object的equals方法:
package com.test.genericity;
public class Demo {
public static void main(String[] args) {
Preson p1 = null;
Preson p2 = new Preson();
//以下代码显示空指针错误
System.out.println(p1.equals(p2));
}
}
该段程序当p1为null的时候不能调用equals方法,程序空指针错误,强行停止程序。而当我们使用Objects.equals的时候,无论参数是否为空都可以调用执行,我们看一看
package com.test.genericity;
/**
* Object.equals操作
* 1. 变量类型:static boolean
* 2. 方法:equals(Object a,Object b)
* 3. 描述:参数相等返回true,否则返回false
* 当两个数为null的时候也可以调用
*
*
*/
//导包操作
import java.util.Objects;
public class Demo4 {
public static void main(String[] args) {
Preson p1 = null;
Preson p2 = new Preson();
//以下代码返回false
System.out.println(Objects.equals(p1,p2));
//以下代码显示错误
//System.out.println(p1.equals(p2));
}
}
java.util.Objects包当中还有很多方法,就不一一举例了,学习首先要知道能有这样一个实现功能的工具,在需要使用的时候可以查看API进行使用!
java.lang.Math类
简介
java.util.Objects是属于java.lang.Object的子类。Math()类包含了用于执行基本数字运算的方法,例如基本指数,对数,平方根和三角函数。
举例使用Math类的方法
以下代码使用了Arrays类当中的方法:
- abs
- min
- max
- round
- floor
- ceil
涉及到的知识点面试点:
- Math有着丰富算术运算方法工具
package com.test.genericity;
/**
* Math
* 1. 进行算术运算时
*/
public class Demo5 {
public static void main(String[] args) {
//取绝对值
System.out.println(Math.abs(-100.234234));
//取最大/小值
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.floor(4.322));
System.out.println(Math.ceil(4.322));
}
}
进行数值相关的运算使用Math()类的方法会提高工作效率,当然的首先要知道能有这样一个实现功能的工具,在需要使用的时候可以查看API进行使用!
java.lang.Arrays – 常用
简介
java.uitl.Arrays是属于java.lang.Object的子类。该包含用于操作数组的各种方法(例如排序和查找),此类还包含一个静态工厂,允许将数组视为列表。
举例使用Arrays类的方法
以下代码使用了Arrays类当中的方法:
- sort
- toString
- copyOf
涉及到的知识点面试点:
- Arrays类有操作数组的各种方法
package com.test.genericity;
import java.util.Arrays;
/**
* Arrays
* 1. 操作数组的各种方法
*/
public class Demo6 {
public static void main(String[] args) {
int[] arr = {10,1,2,3,4,5,6,7,8,9};
//打印地址
System.out.println(arr);
//调用Arrays里面的toString方法打印
System.out.println(Arrays.toString(arr));
//调用Arrays里面的sort方法排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//调用Arrays里面的binarySearch方法查找指定的数据在数组当中的下标
System.out.println(Arrays.binarySearch(arr,1));
//调用Arrays里面的binarySearch方法进行数组扩容(之前扩容特别麻烦)
//打印数组初始
System.out.println(arr.length);
//把数组arr扩容到100
arr = Arrays.copyOf(arr,100);
System.out.println(arr.length);
}
}
因为Arrays类比较常用,就显得比较重要,后续我会整理一个Arrays类的所有方法的表单,加深记忆!
java.math.BigDecimal类
简介
java.math.BigDecimal类是属于java.lang.Number的子类,用于解决小数运算精度的一些问题。
API Note
如果BigDecimal对象用作BigDecimal中的键或SortedSet中的元素,则应谨慎行事,因为BigDecimal的自然顺序与equals不一致。见Comparable,SortedSet或SortedMap获取更多的信息
举例使用BigDecimal类的方法
以下代码使用了BigDecimal类当中的方法:
- add
涉及到的知识点面试点:
- BigDecimal可以解决小数运算的误差问题
- 在使用BigDecimal的时候,需要new出来BigDecimal类型的对象进行操作
- BigDecimal类可以进行数值类型的更改,调用 类型Value() 方法
package com.test.genericity;
import java.math.BigDecimal;
/**
* BigDecimal
* 1. 解决小数运算的误差问题
* 2. new出来一个对象,看作一个double
*/
public class Demo7 {
public static void main(String[] args) {
//这样进行输出的时候得到的结果是不精确的
System.out.println(0.1+0.2);
/**
* 调用BigDecimal类使它精准,结合API查看其他方法
* BigDecimal类中重要的方法:+-*除,获取数值的方法
*
* 1. 在使用BigDecimal的时候,需要new出来BigDecimal类型的对象进行操作
* 2. 对应类里面的方法在使用的时候通过API查找,使用得当才可
*/
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.2");
//add()方法return两数之和,b1和b2的数值都不曾改变
BigDecimal b3 = b1.add(b2);
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
//当我们想把b3变成double类型的方法也存在
b3.doubleValue();
//输出double类型的数据
System.out.println(b3);
}
}
java.util.Date类
简介
java.util.Date类是属于java.lang.Object的子类,表示特定的时间,精度为毫秒。直接子类有:Date,Time,Timestamp.
举例使用Date类的方法
以下代码使用了Date类当中的方法:
- getTime
涉及到的知识点面试点:
- 在创建Date类型的数据的时候,该数据的toString方法就已经被重写,用于打印时间
- print每次使用都是在调用对应数据的toString方法
package com.test.genericity;
import java.util.Date;
/**
* Date--日期和时间
* 1. 表示时刻,精度为毫秒
*/
public class Demo8 {
public static void main(String[] args) {
//在创建Date类型的数据的时候,该数据的toString方法就已经被重写,用于打印时间
Date date = new Date();
//print每次使用都是在调用对应数据的toString方法
System.out.println(date);
//获取当前的毫秒数
System.out.println(date.getTime());
}
}
Date类里面有许多过时的操作,在使用的时候不建议使用这些过时的操作,因为它可能会导致数据错误。详细的操作请查看API。
java.text.DateFormate类
简介
java.text.DateFormate类是属于java.text.Format的子类,它是日期/时间格式化子类的抽象类,它与语言无关的方式格式化和分析日期或时间。
举例使用DateFormate类的方法
以下代码使用了DateFormate类当中的方法:
- 获取该日期距离现在过去多少年。使用Date类的getTime()方法获取时间
- 当然也可以计算一个人现在的年龄
涉及到的知识点面试点:
- DateFormate是一个抽象的类,没有办法直接使用,使用要调用它的子类SimpleDateFormat,该子类有很多日期显示方式
- 当SimpleDateFormat()创建的格式要求后,后面的操作(如parse方法)都得遵循。如SimpleDateFormat(“yyyy-MM-dd HH:mm ss”);创建后, .parse(“yyyy-MM-dd HH:mm ss”);得如这种形式。
package com.test.genericity;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* DateFormat类:
* 1. 可以把new好的Date对象的格式变成生活中经常见到的格式:xxx年xx月xx日xx时xx分...
* 2. 在格式化的时候有一些特殊的字符
* 3. 是一个抽象的类,没有办法直接使用,使用要调用它的子类SimpleDateFormat,该子类有很多日期显示方式
* 4. 获取的是计算机本地的时间
*/
public class Demo9 {
public static void main(String[] args) throws ParseException {
/**
* SimpleDateFormat当中的字母对应
* y : 年
* M : 月
* d : 日
* H : 时
* m : 分
* s : 秒
*
* 2020年9月4日 09:04 33
*/
//SimpleDateFormat("yyyy-MM-dd HH:mm ss")创建的格式要求,后续使用也得按照这样的格式去走
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm ss");
//调用format方法,return一个String类型的数据
//formate:将date对象转换为字符串(yyyy-MM-dd HH:mm ss)
//创建一个一次性对象
format.format(new Date());
System.out.println(format.format(new Date()));
//parse:将yyyy-MM-dd HH:mm ss一段字符串转成date对象
Date date = format.parse("1999-11-12 17:21 33");
//获取该日期距离现在过去多少年。使用Date类的getTime()方法获取时间
System.out.println((new Date().getTime()-date.getTime())/1000/60/60/24/365);
}
}
java.util.Calendar类
简介
java.text.DateFormate类是属于java.lang.Object的子类,它是一个抽象类,可以为在某一特定时刻和一组之间的转换的方法calendar fields如YEAR,MONTH ,DAY_OF_MONTH, HOUR, 等等,以及用于操纵该日历字段,如获取的日期下个星期。瞬间可以用毫秒值表示,该值是1970年1月1日格林威治标准时间1970年1月1日00: 00: 00,000 (格里高利)的Epoch的偏移量(东八区:08: 00: 00,000)。
举例使用Calendar类的方法
以下代码使用了Calendar类当中的方法:
- set
- get
- add
- getTime
- getActualMaximum
涉及到的知识点面试点:
- Calendar使用getInstance()方法创建对象
- 解决了Date类不能进行国际化的问题
- Calendar获取它的年月日的时候得传入一个下标
- c1.get(Calendar.YEAR)当中的YEAR换成int类型的数组1也可以,因为存储这些数据当中的数组内year数据下标为1
package com.test.genericity;
import java.util.Calendar;
import java.util.Date;
/**
* Calendar使用getInstance()方法创建对象
* 因为:抽象类(abstract)无法通过new来创建它
*
* 1. 跟日历相关的操作我们会用到它
* 2. 解决了Date类不能进行国际化的问题
* 3. Calendar把年月日都存在了一个数组里面
*/
public class Demo10 {
public static void main(String[] args) {
//Calendar
//使用getInstance创建对象
Calendar c1 = Calendar.getInstance();
/**
* 因为Calendar把年月日都存在了一个数组里面,Calendar获取它的年月日的时候得传入一个下标
* 如:
* 1. YEAR
* 2. MOUTH
* 3. DAY
* ...
*
* 下面常用方法演示:
* 1. set
* 2. get
* 3. add
*/
//取出日历里面的 年/月
int year = c1.get(Calendar.YEAR);
//YEAR的下标是1,这里直接c1.get(Calendar.YEAR)也可以
int month = c1.get(Calendar.MONTH);
/**
* 1. 国外是周日作为一周的第一天
* 2. 日存储是从0开始的,如一周有0-6(第3天显示2)
* 3. 月份存储也是从0开始。,如一年有0-11(第3月显示2)
*/
System.out.println(year);
System.out.println(month);
//取出今天是这周的第几天。这里为了方便打印直接调用就输出,这种只能使用一次,使用两次的不建议这样写
System.out.println(c1.get(Calendar.DAY_OF_WEEK));
/**
* 1. 因为Calendar的信息都是使用数组存储,所以可以使用set进行设置
* 2. set的数据当然只是所创建的对象的数据,不会更改电脑的设置
* 3. 格式:对象名.set(Calendar.YEAR,需要设置的数据);
*/
c1.set(Calendar.YEAR,2022);
System.out.println(c1.get(Calendar.YEAR));
//使用添加的方法add,add是void类型。传入负数就变成了减
c1.add(Calendar.YEAR,1);
System.out.println(c1.get(Calendar.YEAR));
/**
* 另外建议熟悉的方法有:
* 1. geTime 获取日历时间表示的Date对象
* 2. getActualMaximum 获取各某字段最大的值
*/
//getTime
Date d = c1.getTime();
//getActualMaximum
System.out.println(c1.getActualMaximum(Calendar.MONTH));
}
}
有许多的知识点以及面试点都整理在代码当中。
java.lang.System类
简介
java.text.DateFormate类是属于java.lang.Object的子类,它提供了大量的静态方法、属性。System类包含几个有用的类字段和方法,它无法实例化,System类提供的设施包括标准输入,标准输出和错误输出流;访问外部定义的属性和环境变量;加载文件和库的方法;以及用于快速复制阵列的一部分的实用方法。我们使用得特别频繁的一种类,out等
举例使用System类的方法
GC:
- public static void gc()
- 允许垃圾回收器。调用gc方法表明Java虚拟机花费了大连精力来回收未使用的对象,使得当前占用的内存可以快速重用。当控制方法从调用返回时,Java虚拟机以尽最大努力从所有丢弃的对象中回收空间。
- 呼叫System.gc()实际上等同于呼叫:Runtim.getRuntime().gc()
String类
简介
Java程序中的所有字符串文字都实现为此类的实例。字符串的值是不变的,他们的值在创建后无法更改,字符串缓冲区支持可变字符串。因为Strin对象不可变,所以可以共享他们。
介绍以下方法区与堆:
JDK1.7:
-
方法区(Method Area)
- 又称永久代(Permanent Generation),又称非堆区(Non-Heap space)
- 方法区域被所有线程所共享
-
堆(heap)
逻辑上分为三部分:
- 新生代(Young Generation,常称Young Gen):刚创建的对象都存储在里面,被回收次数小于15次。很快的去问GC,有垃圾很快就会清除
- 老年代(Old Generation,常称OldGen、TenuringGen):回收次数超过15次,会被重复使用
- 永久代(Permanent Generation,常称PermGen):不可能被清除(静态修饰的所有)
以下代码使用了String类当中的元素:
- StringBuffer
- StringBuffer里面的append方法
举例使用String类的方法
package com.test.genericity;
/**
* String类库是我们学习的第一个常用类库
* 1. 任何一个字符串都是此类的实例(对象)
* 2. 字符串的值是不变的,创建后无法更改
* 3. 因为String对象是不可变的,所以他们可以共享(当字符串内容相同,系统默认设置两者地址相同,前提是两者都没有new)
* 4. 数据在字符串常量池进行缓冲,字符串常量池存在方法区(加载代码的内存区域)里面
* 5. new是在内存里开辟空间
* 6. 为你提供这一个方法,那么这一个方法就一定有意义
* 7. 通过加法,字符串拼接能避免尽量避免,很占内存的(数据在永久代里面,不会被回收)
* 8. 如有拼接需求,使用StringBuffer(排队执行)、StringBuilder(同时执行)解决拼接字符串
* 9. StringBuilder/StringBuffer扩容或产生的内存垃圾被及时回收,得出占内存较小(二者操作方法差不多)
* 10. 拼接方法:
* 1.new一个StringBuilder/StringBuffer对象
* 2.使用append方法将内容拼接上
* 11. 想要使用:
* 1.toString方法可以将其转为String
* 2.与String很类似
* 12. StringBuffer是线程安全的实现;StringBuilder是线程不安全的实现
*/
public class Demo11 {
public static void main(String[] args) {
//字符串拼接示例,节省内存
StringBuffer s = new StringBuffer();
s.append("12");
s.append("rqr");
System.out.println(s);
}
}
String类是我们常常用到的类,里面对于字符串的各种操作都需要我们进行学习掌握,以便以后遇到的时候进行熟练、高效的使用。