目录
泛型
泛型的使用
注意
泛型限制类型
泛型中的通配符 ?
作用
常用库类整理
休息日练习
泛型
定义:在调用方法时,我们通常需要传入某种类型的参数,而这种类型,我们可以将其定义成参数(类型形参),这种方法称为泛型。因为我们在传递参数时,有时候我们不确定需要传递哪种类型的参数,或者需要传入多种类型的参数,此时我们就可以用泛型作为类型形参。然后在使用时传入具体的类型。
泛型的使用
泛型类
定义一个泛型类:
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;
}
}
泛型方法
常用写法:public static <T> void print(T a)
private static <T> T 方法名(T a, T b) {}
注意
-
在编译之后程序会采取去泛型化的措施。
-
也就是说Java中的泛型,只在编译阶段有效。
-
在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加
-
类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。
-
在类,方法或接口可以使用多个泛型。如下图

泛型限制类型
-
在使用泛型时, 可以指定泛型的限定区域 ,
- 例如: 必须是某某类的子类或 某某接口的实现类,格式:<T extends 类或接口1 & 接口2>
泛型中的通配符 ?
类型通配符是使用?代替方法具体的类型实参。
1 <? extends Parent> 指定了泛型类型的上届
2 <? super Child> 指定了泛型类型的下届
3 <?> 指定了没有限制的泛型类型
作用
1、 提高代码复用率
2、 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
常用库类整理
Object类功能分析
我们可以看到Objects类是Final的,即不可以被其他类继承,并且它里面的方法都是static的。说明这是一个工具类
接下来我们分析一下他们的功能,废话不说,直接上代码。

-
equals ,deepEquals 比较两个对象是否相等

可以看到equals方法的功能是判断两个对象 是否是同一个对象,或者两个对象是否相等。


deepEquals就比较严格一点,它的功能是首先比较两个对象是否是同一个对象,然后再调用对象的equals方法。
1)首先它比较两个对象是否是同一个对象; 2) 如果不是,再判断它们是否是矩阵,对于矩阵的每个元素,它们是否是同一个对象 3)最后调用对象的equals方法
2 . 计算对象的hashcode
hashCode(Object),hashCode(Object...)
说明: hashCode(Object)是计算单个对象的hashCode , hashCode(Object...)是计算矩阵的hashCode

没什么说的,对象要是为null , hashCode的值为 0


String hashcode

对于矩阵的hashCode : 计算公式 s[0] * 31 ^ (n -1) + s[1 ] * 31 ^ (n-2) + .... + s[n-1] + 31 ^ n
String的hashCode:计算公式 : s[0] * 31^(n-1) + s[1] * 31 ^ (n-2) + ........ + s[n-1]
可以看出 矩阵的hashCode的计算公式比String的hashCode的计算公式多了一个后缀 31^ n
-
toString


加强版的toString多了一个nullDefault ,当对象为null的时候,默认的toString值 ,我觉得是防御性编程的一种体现
4 .compare 比较

可以看到,方法传入了一个Comparator接口,它是一个函数式接口,这也是函数式编程思想的一种体现。
-
判断非null requireNonNull(Object) ,requireNonNull(Object,String messgae)



如果对象为Null ,则抛出异常,否则返回这个对象本身
6.判断对象是否为Null


判断对象是否为Null ,返回true,false
总结: Objects的功能 1) 判断是否相等
2)计算hashCode
3)toString
4)compare比较
5 ) 判断对象是否非Null,并返回这个对象
6 )判断对象是否非Null , 返回true,false
Math类的方法函数

Arrays类
1、填充数组:fill
eg1.
int []arr = new int[5]; Arrays.fill(arr, 2); output(arr);123
结果是:2 2 2 2 2 分析:给所有值赋值2 eg2.
int []arr = new int[5]; Arrays.fill(arr, 1,3,8); output(arr);123
结果是:0 8 8 0 0 分析:给第1位(0开始)到第3位(不包括)赋值8
2、数组元素排序:sort
eg1.
int []arr = {3,2,1,5,4};
Arrays.sort(arr);
output(arr);123
结果是:1 2 3 4 5 分析:给所有数按升序排序 eg2.
int []arr = {3,2,1,5,4};
Arrays.sort(arr,1,3);
output(arr);123
结果是:3 1 2 5 4 分析:给第1位(0开始)到第3位(不包括)排序
3、比较数组元素是否相等:equals
int []arr1 = {1,2,3};
int []arr2 = {1,2,3};
System.out.println(Arrays.equals(arr1,arr2));123
结果是:true 分析:如果是arr1.equals(arr2),则返回false,因为equals比较的是两个对象的地址,不是里面的数,而Arrays.equals重写了equals,所以,这里能比较元素是否相等。 这里补充一下,如果还是不用Arrays.equals,那么我们应该如何重写equals来比较两个数组的元素是否相等呢?这里提供一段代码
//Compare the contents of two int arrays
public static boolean isEquals(int[] a, int[] b)
{
if( a == null || b == null )
{
return false;
}
if(a.length != b.length)
{
return false;
}
for(int i = 0; i < a.length; ++i )
{
if(a[i] != b[i])
{
return false;
}
}
return true;
}1234567891011121314151617181920
4、二分查找法找指定元素的索引值(下标):binarySearch
数组一定是排好序的,否则会出错。找到元素,只会返回最后一个位置 eg1:
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 20));12
结果是:1 分析:能找到该元素,返回下标为1(0开始) eg2:
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 35));12
结果是:-4 分析:找不到元素,返回-x,从-1开始数,如题,返回-4 eg3:
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 0,3,30));12
结果是:2 分析:从0到3位(不包括)找30,找到了,在第2位,返回2 eg4:
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 0,3,40));12
结果是:-4 分析:从0到3位(不包括)找40,找不到,从-1开始数,返回-4
5、截取数组:copeOf和copeOfRange
eg1: copy
int []arr = {10,20,30,40,50};
int []arr1 = Arrays.copyOf(arr, 3);
output(arr1);123
结果:10 20 30 分析:截取arr数组的3个元素赋值给姓数组arr1 eg2: copyOfRange
int []arr = {10,20,30,40,50};
int []arr1 = Arrays.copyOfRange(arr,1,3);
output(arr1);123
结果:20 30 分析:从第1位(0开始)截取到第3位(不包括)
6、其他
还有hashCode,toString,clone等这里就不介绍了,暂时用的少
BigDecimal类
-
add(BigDecimal)
BigDecimal对象中的值相加,返回BigDecimal对象
-
subtract(BigDecimal)
BigDecimal对象中的值相减,返回BigDecimal对象
-
multiply(BigDecimal)
BigDecimal对象中的值相乘,返回BigDecimal对象
-
divide(BigDecimal)
BigDecimal对象中的值相除,返回BigDecimal对象
-
toString()
将BigDecimal对象中的值转换成字符串
-
doubleValue()
将BigDecimal对象中的值转换成双精度数
-
floatValue()
将BigDecimal对象中的值转换成单精度数
-
longValue()
将BigDecimal对象中的值转换成长整数
-
intValue()
将BigDecimal对象中的值转换成整数
10.bigdemical.compareTo(bigdemical2)
将BigDecimal的两个对象进行大小比较
Date类
-
Date类表示特定的时刻,精度为毫秒。 -
在JDK 1.1之前,
Date类还有两个附加功能。 它允许将日期解释为年,月,日,小时,分钟和秒值。 它还允许格式化和解析日期字符串。 不幸的是,这些功能的API不适合国际化。 -
从JDK 1.1开始,
Calendar类应该用于在日期和时间字段之间进行转换, -
而
DateFormat类应该用于格式化和解析日期字符串。 不推荐使用Date中的相应方法。
常用的方法
1.构造方法
Date()//返回当前时间 Date(long date) //返回参数date到1970年1月1日8时的毫秒数
2.常用方法
getTime()//返回调用方法时到1970年1月1日8时的毫秒数 after(Date when) //测试此日期是否在指定日期之后。 before(Date when) //测试此日期是否在指定日期之前。 toString() //将此 Date对象转换为以下形式的 String :
Calendar类
-
Calendar是一个抽象类,不能通过new来创建对象,而是要通过Calendar.getInstance()来创建。
-
年月日在Calendar类中是以数组的形式进行储存。
-
月的数字是从0-11,周是从周日开始算新的一周
-
只要更改过日历,再用get方法获取到的是更改后的日历信息
/**
* set
* get
* add
* getTime:获取日历时间 表示的Date对象
* getActualMaxmum :获取某字段的最大值
* @param args
*/
public static void main(String[] args) {
Calendar cl = Calendar.getInstance();
cl.set(Calendar.YEAR,2021);//设置时间
//获取当前的年月日
int year = cl.get(Calendar.YEAR);
int day = cl.get(Calendar.DAY_OF_YEAR);
cl.add(Calendar.YEAR,10);//时间运算
int add_year = cl.get(Calendar.YEAR);
Date d = cl.getTime();
int Month_Max = cl.getActualMaximum(Calendar.MONTH);//获取月份的最大值
/**
* 获取某月最大天数
*/
cl.set(Calendar.MONTH,1);
int Day_Max = cl.getActualMaximum(Calendar.DAY_OF_MONTH);
String类(绝对重点)
-
String类表示字符串。Java程序中的所有字符串文字(例如"abc")都实现为此类的实例。字符串是不变的; (因为在String类中,字符是以数组的形式来储存的,而数组长度一旦确定,就无法改变。所以字符串是不变的)它们的值在创建后无法更改。因为String对象是不可变的,所以可以共享他们。(说人话就是如果两个字符串内容是完全相同的,那么他们两个则采用同一块内存地址,如下图)

字符串常量池
方法区

堆

方法区的实现的演变

通过加法进行字符串拼接原理


通过加法进行n次字符串拼接,会产生n-1个内存垃圾
StringBuffer和StringBuilder
相同:都是用于字符串拼接。StringBuffer.append()方法进行拼接,StringBuffer()的初始容量是16个字符,当容量满了之后会进行动态扩容。
异:StringBuffer是多个字符串顺序拼接,StringBuilder是多个字符串同时拼接。StringBuffer是线程不安全的实现,StringBuilder是线程安全的实现。

休息日练习
1.逻辑与关键点
* 1.用户输入年月,并储存。 * 2.循环计算该月每天离第一个休息日的天数差(用date对象进行计算),编写函数,传入初始时间和结束时间。 * 3.计算休息日。因为第一个休息日为2号,每三天休息一次,采用绝对时间的计算方式,将天数差%4==2的日期就是休息日 * 4.算出休息日后,需要用字符串拼接来打印【日期】,判断是否为周末,要进行计数。否则。非休息日至今打印(在循环中打印月的当前最大天数) * 5.打印: * 表头 * 周六就换行
-
1.用户输入年月,并储存。
-
2.循环计算该月每天离第一个休息日的天数差(用date对象进行计算),编写函数,传入初始时间和结束时间。
-
3.计算休息日。每三天休息一次,将天数差%4==1的日期就是休息日
-
4.算出休息日后,需要用字符串拼接来打印【日期】,判断是否为周末,要进行计数。否则。非休息日至今打印(在循环中打印月的当前最大天数)
-
5.打印:
-
表头
-
周六就换行
-
视图层
package homewwork_commonLibraries;
import java.util.Calendar;
import java.util.Scanner;
public class Views {
public Calendar input() {
Calendar c = Calendar.getInstance();
input_year(c);
input_month(c);
c.set(Calendar.DAY_OF_MONTH, 1); //初始化每月的日期为1日
return c;
}
//输入年
public void input_year(Calendar c) {
try {
while (true) {
System.out.println("请输入年:");
Scanner input = new Scanner(System.in);
int year = Integer.parseInt(input.nextLine());
if (year < 1970 || year > 9999) {
System.out.println("请输入1970年后有效的年份!");
} else {
c.set(Calendar.YEAR, year);
break;
}
}
} catch (NumberFormatException e) {
System.out.println("请输入数字");
input_year(c);
}
}
//输入月
public void input_month(Calendar c) {
try {
while (true) {
System.out.println("请输入月:");
Scanner input = new Scanner(System.in);
int month = Integer.parseInt(input.nextLine());
if (month < 1 || month > 12) {
System.out.println("你输入的月份有误,请重新输入");
}
else {
int true_month = month - 1;
c.set(Calendar.MONTH, true_month);
break;
}
}
} catch (NumberFormatException e) {
System.out.println("请输入数字");
input_month(c);
}
}
//打印表头
public void print_Header(Calendar c){
//获取周六是第几天
int weekstart = c.get(Calendar.DAY_OF_WEEK);
System.out.println("星期日t星期一t星期二t星期三t星期四t星期五t星期六");
for(int i=1;i<weekstart;i++){
System.out.printf("%-8s","");
}
}
//打印休息日
//打印不了,不要用
public void print_RelaxDay(Calendar c){
StringBuffer sb = new StringBuffer();
//%-8s表示字符串最小显示长度为8字符
StringBuffer s = sb.append("%-8s").append("[").append(c.get(Calendar.DAY_OF_MONTH)).append("]");
System.out.print(sb);
}
//打印工作日
public void print_Workday(Calendar c){
StringBuffer sb = new StringBuffer();
sb.append("%-8s");
sb.append(c.get(Calendar.DAY_OF_MONTH));
System.out.print(sb);
}
}
dao层
package homewwork_commonLibraries;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Dao {
Views v = new Views();
/**
* 初始化将第一次休息日的日期转换为时间戳。
*/
public Date initialize() throws ParseException {
//格式化开始时间
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//设置开始时间
Date startDate = df.parse("2020-02-01");
return startDate;
}
/**
* 计算输入日期与第一次休息日相隔天数
* @param start:第一个休息天
* @param end :当前日期
* @return 间隔天数
*/
public int Day_interval(Date start,Date end){
//获取开始时间戳
long fromTime = start.getTime();
//获取开始时间戳
long toTime = end.getTime();
//计算时间戳差距并转换成天数
int days = (int) ((toTime - fromTime) / (1000 * 60 * 60 * 24));
return days;
}
public void CalculateRelaxDays_print(Calendar c) throws ParseException {
int relax_count = 0; //本月休息日统计
int weekend_count = 0;//本月休息日为周末的统计
int maxDate = c.getActualMaximum(Calendar.DATE);//获取本月最大天数
for(int i=1;i<=maxDate;i++){
c.set(Calendar.DAY_OF_MONTH, i);
Date start = initialize();
Date end= c.getTime();
int gap = Day_interval(start,end);
if (gap%4==1){
//打印休息日
System.out.printf("%-8s","["+c.get(Calendar.DAY_OF_MONTH)+"]");
relax_count++;
if (c.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY||c.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){
//如果这四天包含周末休息天++
weekend_count++;
}
}
else{
//打印工作日
System.out.printf("%-8s", c.get(Calendar.DAY_OF_MONTH));
}
//周六就换行
if (c.get(Calendar.DAY_OF_WEEK)==Calendar.DAY_OF_WEEK){
System.out.println();
}
}
System.out.println();
System.out.println("本月休息的天数有:"+relax_count);
System.out.println("本月轮到周末休息的天数有:"+weekend_count);
}
}
主函数
package homewwork_commonLibraries;
import java.text.ParseException;
import java.util.Calendar;
public class Offday {
public static void main(String[] args) throws ParseException {
Views v = new Views();
Dao dao = new Dao();
Calendar c = v.input();
v.print_Header(c);//打印表头
dao.CalculateRelaxDays_print(c);
}
}
最后
以上就是壮观路灯最近收集整理的关于JavaEE笔记——核心类库的全部内容,更多相关JavaEE笔记——核心类库内容请搜索靠谱客的其他文章。
发表评论 取消回复