Java 学习笔记 2021.6.72021.6.8

210 日期类-Calendar类概述

在这里插入图片描述
Canlendar是抽象类,不能直接创建对象,可以使用其子类来创建对象,或者使用范例方法(本质上也是使用子类)。因此如果某一个方法的返回值是抽象类,那么这个方法需要的是其子类对象。
2.Calendar类的使用方法:(cal是创建的类名)
cal.get(Calendar.YEAR);//年
cal.get(Calendar.MONTH) + 1;//**月(必须要+1)**月从0开始
cal.get(Calendar.DATE);//日
cal.get(Calendar.HOUR_OF_DAY);//时
cal.get(Calendar.MINUTE);//分
cal.get(Calendar.SECOND);//秒
cal.get(Calendar.DAY_OF_WEEK);//星期(Locale.ENGLISH情况下,周日是1,剩下自己推算)
如果拿时间不是为了计算而是展示出来,肯定用SimpleDateFormart了,模式为yyyy-MM-dd HH:mm:ss
其他使用详见https://blog.csdn.net/weixin_38610651/article/details/82796317
个人理解:注意到cal.get里面的参数是Canlndar.YEAR,与创建的cal对象无关,因为YEAR只是一个表示符,在内部YEAR的值就为1,即程序换为:cal.get(1);也是输出cal表示的年份。
3.个人:在帮助文档中的field表示该类的字段的意思,比如Calendar.YEAR;就是一个field。
在这里插入图片描述
注意第二个方法是抽象方法,那是不是不能使用呢?答案肯定是可以使用,既然是抽象方法,那么在子类中肯定是重写了的。而Calendar作为一个抽象类,创建的时候用的是多态的方法,使用了子类对象的,因此这个方法可以正常使用

213 异常

在这里插入图片描述

214 异常-异常处理

在这里插入图片描述
程序运行时发生错误后会生成一个错误类,错误类如果与catch里面的错误类匹配,那么就会把此错误给图中的变量名(也就是下述try代码块中的e),然后运行catch的语句。
范例:

        System.out.println("start!!");
        int[] arr = {1,2,3};
        System.out.println(arr[3]);//错误地点
        System.out.println("end!!!");

上述代码块会报错,导致程序直接终止,不会接着执行。如果想程序跳过错误接着执行,使用刚学习的try:

        System.out.println("start!!");
        int[] arr = {1,2,3};
        try {
            System.out.println(arr[3]);
        }catch (ArrayIndexOutOfBoundsException e){//ArrayIndexOutOfBoundsException是错误类的类名!!!
        //既然已经知道这是运行时异常那么将ArrayIndexOutOfBoundsException改为RuntimeException也是可以的。(多态方式)
            System.out.println("发生了故障");
        }

        System.out.println("end!!!");

最终程序输出:

start!!
发生了故障
end!!!

当然在实际开发中一般不是输出发生了故障,而是追踪错误,所以将System.out.println("发生了故障");改为:e.printStackTrace();,程序最终输出:
在这里插入图片描述

异常-Throwable的成员方法

Throwable是所有错误和异常的祖宗类,只要是此类的错误都可以使用这几个方法。
在这里插入图片描述
注意第一个第二个要自己sout才能显示出来。一般用第三个,显示的信息是最多的。

217 异常-编译时异常和运行时异常的区别在这里插入图片描述

在214中可以看到运行时异常(数组越界),编译时异常必须处理,否则无法通过编译。下面演示编译时异常:
输入代码:

	String s ="2021-06-07";
    SimpleDateFormat dateFormat1 =new SimpleDateFormat("yyyy-MM-dd");
    Date d = dateFormat1.parse(s);
    System.out.println(d);

在parse处显示异常:
在这里插入图片描述
处理方案:同运行时异常:try:

    	String s ="2021-06-07";
        SimpleDateFormat dateFormat1 =new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date d = dateFormat1.parse(s);
            System.out.println(d);
        }catch (java.lang.Exception E){//此处可改为ParseException,写成这样是为了测试如果不知道错误方式能不能调用错误报告
        
            E.printStackTrace();
        }

程序输出:Mon Jun 07 00:00:00 CST 2021

注意:非运行时异常(编译时异常)是指可能出现异常,不一定出现异常,上述代码块中只要s与dateFormat1的格式匹配那么不会出现异常,是正常运行的。但正因为可能有问题,所以必须要处理一下。

异常-throws

跟在方法的小括号之后。
在这里插入图片描述
当某个方法可能会抛出某种异常时用于throws 声明可能抛出的异常,然后交给上层调用它的方法程序处理,即使用此语句时只是将可能会产生的错误抛出,抛出后需要其他的处理。
在运行时异常使用throws,程序不会像try…catch那样继续执行,因此错误只是抛出了嘛没有其他处理了。
在非运行时异常使用throws,用代码演示:


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Exception {
    public static void main(String[] args)  {
        System.out.println("start!!");
        try {//谁调用,谁来处理。这里method调用了,故使用:try...catch
            method();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("end!!!");
    }
    public static void method() throws ParseException {//throws 只是抛出异常
    String s ="2021-06-07";
        SimpleDateFormat dateFormat1 =new SimpleDateFormat("yyyy-MM-dd");

            Date d = dateFormat1.parse(s);
            System.out.println(d);

    }
}

219 异常-自定义异常

自定义异常是为了应对超出Java程序设定之外的异常,比如成绩必须是0-100之间,程序是不知道的。
只要程序继承了Exception,那么就是异常类中的一员。
格式:
在这里插入图片描述
为何带参构造是super(message);,阅读代码源码可知message是向上传递的,最终可以通过printStackTrace()/getMessage()方法看到。自定义异常类的写法目前学到的基本就是写死的,只有类名自己可以改。
下面用代码展示自定义异常:
共分为三个文件:自定义异常类,创建的老师类,老师测试类:
自定义异常类:

在这里插入图片描述
创建的老师类:
在这里插入图片描述
老师测试类:
在这里插入图片描述

在三个类中需要注意的是老师测试类和老师类。
个人:
自定义异常类:自定义异常类格式比较固定,基本上可以说除了类名其他都是固定死的,其作用就是定义了一下程序等会可能会报告错误。
老师类:注意红色箭头,首先注意下面那个箭头,throw(没有s)了一个新的自定义错误,然后把想throw的信息进行有参构造,然后程序会报错,在上面那个箭头那那样写throws 错误类即可(在报错位置按下alt+enter可快捷添加throws)。
老师测试类:由于getscore可能会有错误,因此必须修复,throws是抛出错误,所以这里采取的是有作为的try...catch
在这里插入图片描述

220 集合进阶——Collection

在这里插入图片描述

221 集合进阶——Collection概述和使用

在这里插入图片描述
Collection集合常用方法:
在这里插入图片描述
Collection集合的遍历:
注意是i不是L!!!
在这里插入图片描述
1.如果已经是最后一个元素,继续使用语句 xxx.next();将会报错。故使用next语句之前应该先用hasNext判断一下。
2.迭代器不会时时跟着Collection走,写下下列代码块的语句创建迭代器后,再往p1里面添加元素,迭代器是迭代不到元素的。

		Collection<String> p1 = new ArrayList<String>();
        Iterator<String> it = p1.iterator();

226 集合-List集合

1.List继承自Collection,自然继承了Collection接口的iterator,所以也可以用iterator遍历。也可以用下图中的get方法。
2.相较于Collection特有发放:增删改查四件套
在这里插入图片描述

229 集合-List-并发修改异常

在下列代码中,会在it.next()处报错:

List<String> studentCollection = new ArrayList<String>();
studentCollection.add("林青霞");
studentCollection.add("思无邪");
Iterator<String> it = studentCollection.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("林青霞")) {
        studentCollection.add("JAVA");
    }
}

错误信息如下:

Exception in thread “main” java.util.ConcurrentModificationException
at java.base/java.util.ArrayList I t r . c h e c k F o r C o m o d i f i c a t i o n ( A r r a y L i s t . j a v a : 1042 ) a t j a v a . b a s e / j a v a . u t i l . A r r a y L i s t Itr.checkForComodification(ArrayList.java:1042) at java.base/java.util.ArrayList Itr.checkForComodification(ArrayList.java:1042)atjava.base/java.util.ArrayListItr.next(ArrayList.java:996)

通过翻看源码发现是list.add执行时会修改当前修改次数,而next则会检查当前修改次数与预期修改次数两者不同会报并发修改异常的错误。(翻看源码的过程很繁琐,而且也不太看的懂,视频p229),个人猜测源码的写法可能就是保证执行迭代器next期间不能执行原List集合的add。(注意是迭代器来next,集合来add,不是迭代器来add)
因此改写法,改为get方法获取当前元素(观看源码发现get方法不会检查当前修改次数与预期修改次数),然后再add方法增加元素。

230 集合-List-ListIterator

在这里插入图片描述
使用逆向遍历比较少,了解使用格式。使用正向遍历的使用用ListIterator也比较少,一般直接用Iterator。
在这里插入图片描述
主要是学习到add方法,这里是迭代器的add方法,将229的并发修改异常的代码修改两处:1.将Iterator修改为ListIterator 2.将列表的add方法修改为ListIterator的add方法即可。
翻阅源码发现ListIterator的add方法会将当前修改值与预期修改值先改为一样的值,所以不会报错。

231 集合-List-增强for循环

增强for循环的意义:简化数组和Collection数组的遍历。
在这里插入图片描述
因此现在遍历Collection集合一共有三种方式:普通for,增强for,迭代器。(都要会)
因此后面遍历使用增强for最方便,但是如果操作与索引有关的话就必须用普通for,因为普通for里面用的是get(i);来获取元素。

233 集合-List-数据结构

常见数据结构:
1.栈:一段开口,数据先入后出
2.队列:两端开口,数据先入先出
3.数组:可以通过索引定位,查询任意数据耗时相同,查询速度快;删除时,除了删除数据,还需要将每个数据前移,效率较低,插入数据同理,效率低--------因此数据查询快,增删慢
4.链表:增删快(对比数组),查询慢,因为查询必须从头开始

235 集合-List-List集合子类特点

在这里插入图片描述
在这里插入图片描述

237 集合-List-LinkList特有功能

由于LinkList是链表,因此有一些针对头结点和尾节点的特有方法:增删 查
在这里插入图片描述
其中addLast()与以前学的add()作用完全一样,都是在最后增加元素。

238 集合-set集合

1.set集合概述和特点:
set集合不学习其中的新功能。set集合的特点是元素不重复,重点学习的也是这点。
此外set没有带索引的方法,所以不能使用普通for循环遍历。
此外set是一个接口,因此需要使用一个实现类HashSet来创建对象,HashSet有一个特点:对集合的迭代顺序不作任何保证。
演示:运行下列代码:

 Set<String> s1 = new HashSet<>();
        s1.add("222");
        s1.add("111");
        s1.add("333");
        s1.add("333");
        System.out.println(s1);

系统输出为;

[111, 222, 333]

说明set:重复元素不能添加以及不能保证迭代顺序的特点。

239 set-哈希值

1.哈希值不是对象地址的数值。
2.哈希值是一个int类型的数值。
3.同一对象多次调用hashCode方法返回的哈希值是相同的。默认情况下(不默认的情况:通过重写hashCode方法可以强行让哈希值相同),不同对象的哈希值是不同的

240 Set-HashSet集合概述和特点

在这里插入图片描述
没有带索引的方法,不能使用普通for循环遍历,依然可以使用迭代器和增强for循环来遍历。

241 Set-HashSet保证元素唯一性的原理

个人:最核心的就是HashSet会先比较两个对象的哈希值是否相等,如果相等则会调用对象的equals()方法比较元素本身是否相同,从而保证元素唯一。 记住此点,后面会应用
在这里插入图片描述

242 Set-常见数据结构之哈希表

哈希表是由数组加链表的形式组成(不理解可看视频242);
在这里插入图片描述

243 HashSet存储学生对象并遍历

对代码:

s1 = new Student(20,"林青霞");
s2 =new Student(20,"林青霞");`

s1与s2存储的内容完全相同,但是s1和s2的地址都是new出来的,新生成的,因此结合241,set表存储时会发现s1 ,s2的哈希值不同(甚至调用equals()方法两者也不同,因为名字代表地址,本来就是不同的),所以必须在学生类里面自动生成重写toString方法和hashCode方法

244 Set-LinkedHashSet集合概述和特点

个人:LinkedHashSet经过linked话之后规避了单纯的HashSet不可预测顺序的缺点。
在这里插入图片描述

244 Set-TreeSet

在这里插入图片描述
主义Collection一类的存放的不能是基本类型(String是一个类自然不是基本类型,可以放在Collection里)(至于为什么不能是基本类型,网上说是开发者口味或者设计不周到之类的原因),因此如果Collection里面想存放int之类的基本类型的变量就要用基本类型的包装类(如:Integer类(联想到String也是一个类就好理解了))

246 自然排序Comparable的使用

首先解释为什么有Comparable,往小的来说TreeSet集合会对其中存放的对象进行自然排序,如果是Integer这样的类由于源代码实现了Comparable接口,所以自然可以排序。但是自定义的类,比如学生类,到底是按什么顺序排序系统并不清楚,所以没办法排序,因此需要在学生类里面实现Comparable<E>接口,只需要重写一个compareTo();方法即可。 (不重写的话一个元素都添加不进去的。),例如:

public int compareTo(Object o){
        Student s = (Student)(o);
        return this.ranking - s.ranking;//return正值,代表this排在后面,负数就排在前面,0则代表排名相同,因此这个实现了成绩的从低到高的排序
        //故this放前面就是升序,this放后面就是降序
    }

需要注意如果创建的是TreeSet,那么如果return一直0的话,return 0的那个元素也是添加不进去的,只有第一个元素因为不用比较能添加进去。
往大了说如果需要任意形式的类自然排序都需要实现Comparable<E>接口,并重写compareTo方法
在这里插入图片描述

247 Set-比较器排序Comparator的使用

上小节是TreeSet使用无参构造,自然排序,然后让元素类实现Comparable接口,本节就是使用SetTree的带参(参数就是比较器)排序。在帮助文档中查看Comparator可知这是一个比较器的接口,那么如果想实现这个比较器的接口怎么处理呢?当然是可以创建一个单独的类,但是这样是否太过于麻烦呢?这时候采用的是匿名内部类!!!!! 精彩啊
{匿名内部类知识回顾: 匿名内部类必须继承父类或实现一个接口,作用就是堆继承或实现的方法进行重写,而且匿名内部类没有名字,他的“名字”的那个地方就是他实现的接口或者继承的父类的名字。}
两个蓝块内部就是匿名内部类的实现,按照匿名内部类输入后IDEA会辅助生成compare方法,在图片中:o1可以近似看做上一节中的this,o2可以近似看做传入的参数(是这个用法,但是毕竟是匿名内部类,根本没有this这个说法)。
在这里插入图片描述
所以本节和上节实现的功能是一样的,是实现的接口不一样,而且引入规则的地方不同。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值