JavaSE进阶——Day06

1-时间API


JDK8之后

对时间类进行了优化更新,使用起来更方便,更舒服

8版本前后对比

8版本后:

  1. 设计更合理,功能丰富,使用更方便。

  2. 都是不可变对象,修改后会返回新的时间对象,不会娈失最开始的时间。

  3. 线程安全。

  4. 能精确到毫秒、纳秒。

8版本前:

  1. 设计欠妥,使用不方便,很多都被淘汰了。

  2. 都是可变对象,修改后会丢失最开始的时间信息。

  3. 线程不安全。

  4. 只能精确到毫秒。

LocalDate:年、月、日

LocalTime:时、分、秒

LocalDateTime:年、月、日、时、分、秒

ZoneId:时区

ZonedDateTime:带时区的时间

Instant:时间戳/时间线

DateTimeFormatter:用于时间的格式化和解析

Duration:时间间隔(时、分、秒,纳秒)

Period:时间间隔(年,月,日)

日历类LocalDateTime

LocalDate:代表本地日期(年、月、日、星期)

LocalTime:代表本地时间(时、分、秒、纳秒)

LocalDateTime:代表本地日期、时间(年、月、日、星期、时、分、秒、纳秒)

对象的创建方式

用LocalDateTime中的now();或者of();方法

注意对象创建后不可修改,一定要进行接收。

.now(); 当前时间

.of(); 设置时间

package com.lyl.jdk8;
​
import java.time.LocalDateTime;
​
public class Demo {
    public static void main(String[] args) {
        //获取此刻的时间对象
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        //获取指定的时间对象
        LocalDateTime of = LocalDateTime.of(2008,8,22,11,30,28);
        System.out.println(of);
    }
}

获取年/月/日/时/分/秒:对应的对象名.getXXX方法

注意:getMonth();getDayOfWeek;返回的是对应的对象(例如:MARCH),想转换成数字可以用getValue();方法

修改年月日时分秒相关的方法

LocalDateTime、LocalDate、LocalTime都是不可变的,下列方法返回的是一个新的对象

minus:减

plus:加

with:设置(每次只能改一个值)

总结

LocalDate LocalTime LocalDateTime对象如何创建?

now:当前时间

of:指定时间

2.获取的相关方法是?

getXxx();

getYear()getMonth()getMonthValue()...

3.修改的相关方法是?

withXxx:修改

minusXxx:减

plusXxx:加

4.注意点:

LocalDateTime、LocalDate、LocalTime都是不可变的 调用修改的相关方法,返回的都是新的对象

日期格式化类DateTimeFormatter

用于时间的格式化和解析(替代SimpleDateFormatter)

对象的创建方式

调用DateTimeFormatter类中的.ofPattern("格式");方法

package com.lyl.jdk8;
​
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
​
public class DateTimeFormatterDemo {
    public static void main(String[] args) {
        //创建当前时间对象
        LocalDateTime nowTime = LocalDateTime.now();
        //创建用于格式化和解析的对象
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年M月d日");
        //格式化
        String format = dtf.format(nowTime);
        System.out.println(format);
        //解析 因为只有年月日,所以用LocalDate
        LocalDate localDate = LocalDate.parse(format,dtf);
        System.out.println(localDate);
    }
}

注意:定义格式中俩MM和俩dd改成单M和单d

时间类

.now();获取当前时间

.atZone("时区");获取指定时区时间(做国外业务需要使用)

注意:亚洲中国只有上海、重庆

ZoneId类(时区类)

Instant时间戳

  • 用于表示时间的对象,类似之前所学习的Date

ZoneDateTime类(带时区)

思路

  1. 确定业务环境

  2. 国外考虑时区,用ZoneId

  3. 国内用LocalDateTime

工具类

Period类

Period.between创建对象

用于计算两个“日期”间隔(年、月、日)

Duration类

Duration.between创建对象

用于计算两个“时间”间隔(秒,纳秒)

ChronoUnit类

用于计算两个“日期”间隔

ChronoUnit.静态年/月 /日等等.between(时间1,时间2):时间2-时间1

练习

计算时间间隔

package com.lyl.test;
​
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
​
public class BirthdayTest {
    public static void main(String[] args) {
        //1.创建当前时间对象
        LocalDate localDate = LocalDate.now();
        //2.创建生日时间对象
        LocalDate birthday = LocalDate.of(2001,10,11);
        //3.计算时间间隔(年)
        long result = ChronoUnit.YEARS.between(birthday, localDate);
        System.out.println(result);
    }
}

输出结果:21

2-集合


集合分为单列集合和双列集合

  • Collection单列集合,每个元素(数据)只包含一个值。

  • Map双列集合,每个元素包含两个值(键值对)。

Collection集合体系

描述:不同的集合,底层的数据结构不同,适用的场景也不同

目标:能够独立分析需求,选对合适的集合

  • List接口:存取有序,有索引,可以存储重复的

ArrayList类:底层是数组实现(查询和修改快,增删慢)

LinkedList类:底层是链表实现(查询和修改慢,增删相对较快,首尾操作极快)

  • Set接口:存取无序,没有索引,不能存储重复的

TreeSet:底层是红黑树结构

HashSet:底层是哈希表结构

LinkedHashSet:底层哈希表+双向链表

  • Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。

Collection API

迭代器遍历

  • 遍历就是一个一个的把容器中的元素访问一遍。

  • 迭代器在到ava中的代表是Iterator,迭代器是集合的专用遍历方式。

  1. 获取迭代器

    Iterator<Student> it = c.iterator();

    接口的引用=实现类的对象

  2. 循环判断集合中是否还有元素

    while(it.hasNext())

  3. 调用next方法取出元素

sout.(it.next());

迭代器源码执行流程

增强for循环

JDK5版本之后出现的一种迭代器的语法糖,底层也是一个迭代器

  • 既可以遍历集合也可以遍历数组。 

  • 它是JDK5之后出现的,其内部原理是一个teratori迭代器,遍历集合相当于是迭代器的简化写法。

  • 实现Iterable接口的类才可以使用迭代器和增强for,Collection接口已经继承了Iterable接口。

格式:

for(元素数据类型 变量名 : 数组或者Collection集合) {
​
         //在此处使用变量即可,该变量就是元素
​
}

Lambda表达式遍历集合

Collection结合Lambda遍历的API

匿名内部类: 

Collection<String> lists = new ArrayList<>();
...
lists.forEach(new Consumer<String>() {   
    @Override    
    public void accept(String s) {
    System.out.println(s);
    }
});

转换为Lambda表达式:

 lists.forEach(s -> {System.out.println(s);
             });
//  lists.forEach(s -> System.out.println(s));

练习:影片信息在程序中的表示

需求:某影院系统需要在后台存储上述三部电影,然后依次展示出来

属性:电影名name 评分score 主演acotr

package com.lyl.test;
​
import com.lyl.domain.Movie;
​
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;
​
public class MovieTest {
    public static void main(String[] args) {
        Collection<Movie> c = new ArrayList<>();
        c.add(new Movie("肖申克救赎",9.7,"蒂姆罗宾斯"));
        c.add(new Movie("霸王别姬",9.6,"张国荣"));
        c.add(new Movie("阿甘正传",9.5,"汤姆汉克斯"));
        //1、迭代器遍历
        Iterator<Movie> iterator = c.iterator();
        while (iterator.hasNext()){
            Movie next = iterator.next();
            System.out.println(next);
        }
        //2、增强for循环遍历
        for (Movie movie : c) {
            System.out.println(movie);
        }
        //3、forEach遍历
        c.forEach(movie -> System.out.println(movie));
    }
}

数据结构

概述

  • 数据结构是计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。

  • 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率

  • 后进先出,先进后出

    数据进入栈模型的过程称为:压/进栈

    数据离开栈模型的过程称为:弹/出栈

队列

  • 先进先出,后进后出

    数据从后端进入队列模型的过程称为:入队列

    数据从前端离开队列模型的过程称为:出队列

数组

  • 查询速度快:查询数据通过地址值和索引定位,查询任意数据耗时相同。(元素在内存中是连续存储的) 

  • 删除效率低:要将原始数据删除,同时后面每个数据前移

  • 添加效率极低:添加位置后的每个数据后移,再添加元素。

    数组是一种查询快,增删慢的模型

链表

  • 链表中的元素是在内存中不连续存储的,每个元素节点包含数据值和下一个元素的地址

  • 链表查询慢,无论查询哪个数据都要从头开始找(单链表)

  • 链表增删相对快

    • 单链表:查询的时候,只能从头开始找

    • 双链表:查询的时候,可以从头找也可以从尾找

    单向链表:每一个节点,记录下一个节点的地址

    双向链表:每一个节点,记录下一个节点的地址的同时,还记录上一个节点的地址

List的实现类的底层原理

  • List集合因为支持索引,所以多了很多索引操作的独特api,其他Collection的功能List也都继承了。

  • List派系下面的集合,多了一种遍历方式,可以使用普通for循环进行遍历(因为它有索引)

ArrayList底层是基于数组实现的:根据索引定位元素快,增删相对慢。 

LinkedList底层基于双链表实现的:查询元素慢,增删首尾元素是非常快的。

ArrayList 长度可变原理

  • 底层源码执行流程

    创建集合对象时,集合默认为空,只有调用add方法时才会创建一个长度为10的数组,当满后继续添加元素,扩容1.5倍长度

LinkedList的特点

  • 底层数据结构是双链表,查询慢,首尾操作的速度是极快的,所以多了很多首尾操作的特有API。

细节:

List.get(i):表面来看是根据索引获取元素,但是这个集合是LinkedList,底层是链表结构,找元素的时候:

1.判断你要查找的元素,离头部近,还是离尾部近

2,离头部近:从头开始查找(正序遍历)

3.离尾部近:从尾开始查找(倒序遍历)

代码目标:

1,集合会创建,数据会添加

2,能够进行赠删改查

3,掌握List集合的4中遍历方式(迭代器,增强for,forEach,普通for)

并发修改异常

迭代器遍历集合的时候,使用集合对象,调用添加或删除,修改的方法,操作集合中的元素,就会出现并发修改异常

  • (迭代器,集合对象)在并发操作

解决方案:

  • 迭代器在遍历的时候,使用迭代器自己的删除方法

细节:如果使用集合对象,删除的是倒数第二个元素,就不会出现并发修改异常

结论:逃过了编译期的异常检查


集合在遍历的过程中进行删除操作:

1.迭代器

  • 不需要手动i--操作,源码中自动做了这件事情

2.增强for

  • 不能删除

3.forEach

  • 不能删除

4.普通for

A:正序遍历,索引--

B:倒序遍历

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值