JavaEE笔记——核心类库

目录

 

泛型

泛型的使用

注意

泛型限制类型

泛型中的通配符 ?

作用

常用库类整理

休息日练习


泛型

定义:在调用方法时,我们通常需要传入某种类型的参数,而这种类型,我们可以将其定义成参数(类型形参),这种方法称为泛型。因为我们在传递参数时,有时候我们不确定需要传递哪种类型的参数,或者需要传入多种类型的参数,此时我们就可以用泛型作为类型形参。然后在使用时传入具体的类型。

泛型的使用

泛型类

定义一个泛型类: 
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中的泛型,只在编译阶段有效。

  • 在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加

  • 类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。

  • 在类,方法或接口可以使用多个泛型。如下图

泛型限制类型

  1. 在使用泛型时, 可以指定泛型的限定区域 ,

    - 例如: 必须是某某类的子类或 某某接口的实现类,格式:<T extends 类或接口1 & 接口2>

泛型中的通配符 ?

类型通配符是使用?代替方法具体的类型实参。

1 <? extends Parent> 指定了泛型类型的上届

2 <? super Child> 指定了泛型类型的下届

3 <?> 指定了没有限制的泛型类型

作用

1、 提高代码复用率

2、 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)

常用库类整理

Object类功能分析

我们可以看到Objects类是Final的,即不可以被其他类继承,并且它里面的方法都是static的。说明这是一个工具类

接下来我们分析一下他们的功能,废话不说,直接上代码。

img

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

img

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

img

img

deepEquals就比较严格一点,它的功能是首先比较两个对象是否是同一个对象,然后再调用对象的equals方法。

1)首先它比较两个对象是否是同一个对象; 2) 如果不是,再判断它们是否是矩阵,对于矩阵的每个元素,它们是否是同一个对象 3)最后调用对象的equals方法

2 . 计算对象的hashcode

hashCode(Object),hashCode(Object...)

说明: hashCode(Object)是计算单个对象的hashCode , hashCode(Object...)是计算矩阵的hashCode

img

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

img

img

String hashcode

img

对于矩阵的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

  1. toString

img

img

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

4 .compare 比较

img

可以看到,方法传入了一个Comparator接口,它是一个函数式接口,这也是函数式编程思想的一种体现。

  1. 判断非null requireNonNull(Object) ,requireNonNull(Object,String messgae)

img

img

img

如果对象为Null ,则抛出异常,否则返回这个对象本身

6.判断对象是否为Null

img

img

判断对象是否为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类

  1. add(BigDecimal)

    BigDecimal对象中的值相加,返回BigDecimal对象

  2. subtract(BigDecimal)

    BigDecimal对象中的值相减,返回BigDecimal对象

  3. multiply(BigDecimal)

    BigDecimal对象中的值相乘,返回BigDecimal对象

  4. divide(BigDecimal)

    BigDecimal对象中的值相除,返回BigDecimal对象

  5. toString()

    将BigDecimal对象中的值转换成字符串

  6. doubleValue()

    将BigDecimal对象中的值转换成双精度数

  7. floatValue()

    将BigDecimal对象中的值转换成单精度数

  8. longValue()

    将BigDecimal对象中的值转换成长整数

  9. 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);
​
​
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值