IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JDK8新特性 -> 正文阅读

[JavaScript知识库]JDK8新特性


在这里插入图片描述

Java 8 (?称为 jdk 1.8) 是 Java 语?开发的?个主要版本。 Oracle 公司于 2014 年 3 ? 18 ?发布Java 8,它?持函数式编程,新的 JavaScript 引擎,新的?期 API,新的Stream API 等。

  • Lambda 表达式 ? Lambda允许把函数作为?个?法的参数(函数作为参数传递进?法中)。
  • ?法引? ? ?法引?提供了?常有?的语法,可以直接引?已有Java类或对象(实例)的?法或构造器。与lambda联合使?,?法引?可以使语?的构造更紧凑简洁,减少冗余代码。
  • 默认?法 ? 默认?法就是?个在接???有了?个实现的?法。
  • Stream API ?新添加的Stream API(java.util.stream) 把真正的函数式编程?格引?到Java中。
  • Date Time API ? 加强对?期与时间的处理。
  • Optional 类 ? Optional 类已经成为 Java 8 类库的?部分,?来解决空指针异常。
  • Nashorn, JavaScript 引擎 ? Java 8提供了?个新的Nashorn javascript引擎,它允许我们在JVM上运?特定的javascript应?。 在 Java 11 已经不可?了

其中核?:Lambda表达式和Stream API

第?节:Lambda表达式

1.1 使?lambda表达式

Lambda表达式可以看成是匿名内部类,Lambda 允许把函数作为?个?法的参数(函数作为?法参数传递),将代码像数据?样传递,使? Lambda 表达式可以使代码变的更加简洁紧凑。

Lambda表达需要函数式接?的?持。

函数式接?(Functional Interface)就是?个有且仅有?个抽象?法,但是可以有多个?抽象?法的接?(jdk1.8以后可以在接?中定义?抽象?法,但是该?法需要使?default或者static修饰,使?default修饰的?法也称为默认?法)。

函数式接?可以被隐式转换为 lambda 表达式。

JDK 1.8 之前已有的函数式接?:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

JDK 1.8 新增加的函数接?:

  • java.util.function

基本语法:

<函数式接?> <变量名> = (参数1,参数2...) -> {
	//?法体
}

案例1:

public class Demo1 {
    public static void main(String[] args) {
        //匿名内部类
       /* Runnable runnable = new Runnable(){
            @Override
            public void run() {
                System.out.println("run");
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();*/
        //表达式
       /* Runnable runnable=()->{
            System.out.println("run-----");
        };
        Thread thread = new Thread(runnable);
        thread.start();*/


        //集合中进行字符串长度的排序
       /* Comparator<String> comparator=new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.length()-o1.length();
            }
        };*/
        Comparator<String> comparator=(o1,o2)->{
            return o1.length()-o2.length();
        };
        List list=new ArrayList<>();
        list.add("aaa");
        list.add("a");
        list.add("aa");

        Collections.sort(list,comparator);

        for (Object o : list) {
            System.out.println(o);
        }
    }
}

需求1:有?个员?集合,获取年龄?于25的员?信息(数据筛选)

public class Users {
    private String name;
    private int age;
    private int salary;

    @Override
    public String toString() {
        return "Users{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }

    public Users() {
    }

    public Users(String name, int age, int salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }
}

测试类:

public class TestUsers {
    //限定年龄
    public static List filterAge(List<Users> list){
        List userList=new ArrayList();
        for (Users users : list) {
            if(users.getAge()>=25){
                userList.add(users);
            }
        }
        return userList;
    }

    //限定工资大于1000
    public static List filterSalary(List<Users> list){
        List userList=new ArrayList();
        for (Users users : list) {
            if(users.getSalary()>=1000){
                userList.add(users);
            }
        }
        return userList;
    }

    public static void main(String[] args) {
        List list=new ArrayList();
        list.add(new Users("aa",18,900));
        list.add(new Users("aa2",25,2000));
        list.add(new Users("aa3",30,3000));
        list.add(new Users("aa4",18,4000));
        list.add(new Users("aa5",29,5000));
        //限定出大于25岁的用户
       // List list2 = filterAge(list);
        List list2 = filterSalary(list);
        for (Object o : list2) {
            System.out.println(o);
        }
    }
}

问题:如果再添加类似需求,需要再添加?个?法。如何解决?

  1. 使?策略设计模式
//定义?个接?
public interface MyFilter<T> {
    public boolean test(T t);
}
//按照年龄过滤
public class AgeFilter implements MyFilter<Users> {
    @Override
    public boolean test(Users users) {
        return users.getAge()>=25;
    }
}
//按照?资过滤
public class SalaryFilter implements MyFilter<Users> {
    @Override
    public boolean test(Users o) {
        return o.getSalary()>=1000;
    }
}

测试类:

public class TestUsers2 {
    //限定年龄或工资
    public static List filter(List<Users> list, MyFilter myFilter){
        List userList=new ArrayList();
        for (Users users : list) {
            if(myFilter.test(users)){
                userList.add(users);
            }
        }
        return userList;
    }

    public static void main(String[] args) {
        List list=new ArrayList();
        list.add(new Users("aa",18,900));
        list.add(new Users("aa2",25,2000));
        list.add(new Users("aa3",30,3000));
        list.add(new Users("aa4",18,4000));
        list.add(new Users("aa5",29,5000));
        //限定出大于25岁的用户
        List list2 = filter(list,new AgeFilter());
       // List list2 = filter(list,new SalaryFilter());
        for (Object o : list2) {
            System.out.println(o);
        }
    }
}
  1. 使?Lambada表达式优化策略模式(不创建实现类)
public interface MyFilter2<Users> {
    public boolean test(Users t);
}
public class TestUsers3 {
    //限定年龄或工资
    public static List filter(List<Users> list, MyFilter2<Users> myFilter2){
        List userList=new ArrayList();
        for (Users users : list) {
            if(myFilter2.test(users)){
                userList.add(users);
            }
        }
        return userList;
    }

    public static void main(String[] args) {
        List list=new ArrayList();
        list.add(new Users("aa",18,900));
        list.add(new Users("aa2",25,2000));
        list.add(new Users("aa3",30,3000));
        list.add(new Users("aa4",18,4000));
        list.add(new Users("aa5",29,5000));
        //限定出大于25岁的用户
       // List list2 = filter(list,(u)->u.getAge()>=30);
        List list2 = filter(list,(u)->u.getSalary()>=2000);
        for (Object o : list2) {
            System.out.println(o);
        }
    }
}
  1. 使?Stream API再优化lambda表达式
public class TestUsers4 {
    public static void main(String[] args) {
        List<Users> list=new ArrayList();
        list.add(new Users("aa",18,900));
        list.add(new Users("aa2",25,2000));
        list.add(new Users("aa3",30,3000));
        list.add(new Users("aa4",18,4000));
        list.add(new Users("aa5",29,5000));
        //限定出大于25岁的用户
        list.stream().filter(u->u.getAge()>=25).forEach(System.out::println);
        //工资限定
        int a=10;
        list.stream().filter((u)->u.getSalary()>=2000).forEach(u1-> System.out.println(u1+","+a));
       /*// List list2 = filter(list,(u)->u.getAge()>=30);
        List list2 = filter(list,(u)->u.getSalary()>=2000);
        for (Object o : list2) {
            System.out.println(o);
        }*/
    }
}

1.2使?lambda表达式注意事项

Lambda引?了新的操作符: ->(箭头操作符),->将表达式分成两部分

左侧:(参数1,参数2…)表示参数列表;

右侧:{}内部是?法体

  1. 形参列表的数据类型会?动推断;
  2. 如果形参列表为空,只需保留();
  3. 如果形参只有1个,()可以省略,只需要参数的名称即可;
  4. 如果执?语句只有1句,且?返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执?语句也保证只有1句;
  5. lambda不会?成?个单独的内部类?件;
  6. lambda表达式若访问了局部变量,则局部变量必须是final的,若是局部变量没有加final关键字,系统会?动添加,此后在修改该局部变量,会报错。

Lambda表达式的语法总结: () -> ();

前置语法
?参数?返回值() -> System.out.println(“Hello WOrld”)
有?个参数?返回值(x) -> System.out.println(x)
有且只有?个参数?返回值x -> System.out.println(x)
有多个参数,有返回值,有多条lambda体语句(x,y) -> {System.out.println(“xxx”);return xxxx;};
有多个参数,有返回值,只有?条lambda体语句(x,y) -> xxxx

?诀:左右遇?省括号,左侧推断类型省

注:当?个接?中存在多个抽象?法时,如果使?lambda表达式,并不能智能匹配对应的抽象?法,因此引?了函数式接?的概念

1.3函数式接?

如果?个接?只有?个抽象?法,则该接?称之为函数式接?,函数式接?可以使?Lambda表达式,lambda表达式会被匹配到这个抽象?法上 。

为了确保你的接??定达到这个要求,你只需要给你的接?添加 @FunctionalInterface 注解,编译器如果发现你标注了这个注解的接?有多于?个抽象?法的时候会报错的。

@FunctionalInterface
interface Converter<F, T> {
	T convert(F from);
}
Converter<String, Integer> c = (from) -> Integer.valueOf(from);
Integer converted = c.convert("123");
System.out.println(converted); // 123

Java为了程序员?便使?Lambda表达式,Java内置了四个核?函数式接?

在这里插入图片描述
提供四个核?函数式接?

  • Consumer 消费型 有参?返回值
  • Supplier 供给型 ?参有返回值
  • Function 函数型 有参有返回值
  • Predicate 断?型 有参返回boolean值
public class Demo1 {
    //测试consumer
    public static void a(int money, Consumer consumer){
        consumer.accept(money);
    }
    //supplier
    public static List b(Supplier supplier){  //get()
          List list=new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(supplier.get());
        }
        return list;
    }

    public static List c(List<String> list, Predicate<String> predicate){
        List newList=new ArrayList();
        for (String s : list) {
            if(predicate.test(s)){
                newList.add(s);
            }
        }
        return newList;
    }

    public static void main(String[] args) {
        //测试consumer
       /* Consumer consumer=(m)->{
            System.out.println("这是"+m+"钱");
        };
        a(300,consumer);*/
        /*Supplier supplier=()->{return  new Random().nextInt();};
        List list = b(supplier);
        for (Object o : list) {
            System.out.println(o);
        }*/
        //将字符串转换成大写
        /*Function<String,String> function=(t)->{return  t.toUpperCase();};
        String abc = function.apply("abc");
        System.out.println(abc);*/
        List list=new ArrayList();
        list.add("abc");
        list.add("bcd");
        list.add("ccd");
        list.add("acd");
        list.add("aqqqcd");
        List list1 = c(list, (s) -> s.startsWith("a"));
        for (Object o : list1) {
            System.out.println(o);
        }
    }
}

第?节:?法引?

使?“::”操作符将?法名和对象或类的名字分隔开来。以下是四种使?情况:

  • 对象 :: 实例?法
  • 类 :: 静态?法
  • 类 :: 实例?法
  • 类 :: new
public class Test {
    public static void main(String[] args) {
        //对象::实例方法
       /* Consumer c=(s)->System.out.println(s);
        c.accept("abc");*/
        Consumer c=System.out::println;
        c.accept("abcd");

        //类::静态方法
        //Comparator<Integer> comparator=(o1,o2)->Integer.compare(o1,o2);
        Comparator<Integer> comparator=Integer::compare;
        int rs = comparator.compare(10, 1);
        System.out.println(rs);

        //类::实例方法
        //BiPredicate<String,String> biPredicate=(s1,s2)->s1.equals(s2);
        BiPredicate<String,String> biPredicate=String::equals;
        boolean test = biPredicate.test("abc1", "abc");
        System.out.println(test);

        //类::new
       // Supplier<Users> supplier=()->new Users();
        Supplier<Users> supplier=Users::new;
        Users users = supplier.get();
        System.out.println(users);

        //数组引用
        MyArray<String> myArray=(n)->new String[n];
        //等价于
        MyArray<String> myArray2=String[]::new;
        String[] strings = myArray2.get(10);
        System.out.println(strings.length);
    }
}
public interface MyArray<T> {
	T[] get(int count);
}
public interface MySupplier<T> {
	T get(String name,int age); //参数列表的类型要和构造?法的类型相同
}

第三节:Stream API

Stream是Java8中处理数组、集合的抽象概念,它可以指定你希望对集合进?的操作,可以执??常复杂的查找、过滤和映射数据等操作。使?Stream API对集合数据进?操作,就类似于使?SQL执?的数据库查询。也可以使?Stream API来并?执?操作。

简单应?:统计?个字符串类型集合中,所有?度?于3的元素个数。

public static void main(String[] args) {
	//传统实现
	List<String> data=new ArrayList<>();
	data.add("hello");
	data.add("world");
	data.add("ni");
	data.add("apple");
	data.add("china");
	
	int count = 0;
	for (String s : data) {
		if (s.length() > 3)
			count++;
	}
	System.out.println(count);
	//Stream API
	long count2= data.stream().filter(s->s.length()>3).count();
	System.out.println(count2);
}

上?代码中stream?法会为字符串列表?成?个Stream。filter?法会返回只包含字符串?度?于3的?个Stream,然后通过count?法计数。

3.1 什么是Stream?

?个Stream表?上与?个集合很类似,集合中保存的是数据,?流中是对数据的操作。

特点:

  • Stream ??不会存储元素。
  • Stream 不会改变源对象。相反,他们会返回?个持有结果的新Stream。
  • Stream 操作是延迟执?的。这意味着他们会等到需要结果的时候才执?。
  • Stream遵循“做什么,?不是怎么去做”的原则。只需要描述需要做什么,?不?考虑程序是怎样实现的。

3.2 如何使?Stream API

使?Stream,会有三个阶段(步骤):

  1. 创建?个Stream。 (创建)
  2. 在?个或多个步骤中,将初始Stream转化到另?个Stream的中间操作。 (中间操作)
  3. 使??个终?操作来产??个结果。该操作会强制他之前的延迟操作?即执?。在这之后,该Stream就不会在被使?了。(终?操作)

3.2.1 Stream的创建?法

public class Test2 {
    public static void main(String[] args) {
    //创建Stream
        //方法1:Stream.of()
       /* Stream<String> aa = Stream.of("aa", "bb", "cc", "dd");
        aa.forEach(System.out::println);*/
        //方法2:Arrays工具类
        /*String[] strs={"aa","bb","ddd"};
        Stream<String> stream = Arrays.stream(strs);
        stream.forEach(System.out::println);*/
        //方法3:使用集合的Stream()方法
      /*  ArrayList<Object> objects = new ArrayList<>();
        objects.add("ac");
        objects.add("ac");
        objects.add("ac");
        objects.stream().forEach(System.out::println);*/

        //方法4:创建无限流
        //4.1 迭代
        Stream<Integer> iterate = Stream.iterate(0, n -> n + 2);
        iterate.limit(5).forEach(System.out::println);
        System.out.println("===========================");
        //4.2 生成
        Stream<Integer> generate = Stream.generate(() -> new Random().nextInt());
        generate.limit(5).forEach(System.out::println);
    }
}

3.2.2 Stream中间操作

中间操作包括:map (mapToInt, flatMap 等)、 filter、distinct、sorted、peek、limit、skip、parallel、sequential、unordered。

多个中间操作可以连接起来形成?个流?线,除?流? 线上触发终?操作,否则中间操作不会执?任何的处理! ?在终?操作时?次性全部处理,称为“惰性求值”。

public class Test3 {
    public static void main(String[] args) {

        List<Users> usersList=new ArrayList<>();
        usersList.add(new Users("xxx", 30, 10000));
        usersList.add(new Users("yyy", 29, 8000));
        usersList.add(new Users("zzz", 22, 12000));
        usersList.add(new Users("张三", 21, 20000));
        usersList.add(new Users("李四", 32, 22000));
        usersList.add(new Users("李四", 32, 22000));
        //1.过滤
       // usersList.stream().filter((u)->u.getAge()>25).forEach(System.out::println);
        //2 分页
      //  usersList.stream().limit(5).forEach(System.out::println);
        //3 跳过
       // usersList.stream().skip(5).limit(5).forEach(System.out::println);
        //4 去重
        /*List list1=new ArrayList();
        list1.add("abc");
        list1.add("abc1");
        list1.add("abc");
        list1.add("abc2");
        list1.stream().distinct().forEach(System.out::println);*/
        //5 映射(获取部分数据)-map(Function(T,R))
       // usersList.stream().map((e)->e.getName()).forEach(System.out::println);

        //6.排序
        List list2=new ArrayList();
        list2.add(111);
        list2.add(4223);
        list2.add(2);
        list2.add(23);
        list2.add(3);
      //  list2.stream().sorted().forEach(System.out::println);
        //6.1 排序内容为对象时?
        usersList.stream().sorted((o1,o2)->o2.getAge()-o1.getAge()).forEach(System.out::println);
    }
}

3.2.3 Stream 的终?操作

终?操作包括:forEach、forEachOrdered、toArray、reduce、collect、min、max、count、anyMatch、allMatch、noneMatch、findFirst、findAny、iterator。

遍历

  • forEach

查找和匹配

  • allMatch——检查是否匹配所有元素
  • anyMatch——检查是否?少匹配?个元素
  • noneMatch——检查是否没有匹配的元素
  • findFirst——返回第?个元素
  • findAny——返回当前流中的任意元素
  • max——返回流中最?值
  • min——返回流中最?值
public class Test4 {
    public static void main(String[] args) {

        List<Users> usersList=new ArrayList<>();
        usersList.add(new Users("xxx", 30, 10000));
        usersList.add(new Users("yyy", 29, 8000));
        usersList.add(new Users("zzz", 22, 12000));
        usersList.add(new Users("张三", 21, 20000));
        usersList.add(new Users("李四", 32, 22000));
        usersList.add(new Users("李四", 32, 22000));
        Stream<Users> stream = usersList.stream();
        //1.全部匹配
       /* boolean b = stream.allMatch((u) -> u.getAge() == 29);
        System.out.println(b);*/
        //2.至少匹配一个
        /*boolean b = stream.anyMatch((u) -> u.getAge() == 29);
        System.out.println(b);*/
        //3.检查都不匹配的
      /*  boolean b = stream.noneMatch((u) -> u.getAge() == 35);
        System.out.println(b);*/
        //4.返回第一个元素
       /* Optional<Users> first = stream.findFirst();
        System.out.println(first.get());*/
        //5.返回总条数
       /* long count = stream.count();
        System.out.println(count);*/
        //6.最大值 最高的工资
        /*Optional<Users> max = stream.max((u1, u2) -> u1.getSalary() - u2.getSalary());
        System.out.println(max.get());*/
        //7.最小值
       /* Optional<Users> min = stream.min((u1, u2) -> u1.getSalary() - u2.getSalary());
        System.out.println(min.get());*/
        //8.终止操作
        /*stream.forEach(System.out::println);*/
        //9.归约(统计操作)-计算总的工资
     /*   Optional<Integer> reduce = stream.map((u) -> u.getSalary()).reduce((s1, s2) -> s1 + s2);
        System.out.println(reduce.get());*/
        //10.collect() 收集
        List<String> collect = stream.filter((u) -> u.getAge() >= 25).map(Users::getName).distinct()
                .collect(Collectors.toList());
        collect.forEach(System.out::println);
    }
}

3.2.4 并?操作

Stream有串?和并?两种,串?Stream上的操作是在?个线程中依次完成,?并?Stream则是在多个线程上同时执?。

计算?下排序这个Stream要耗时多久:

public class Test5 {
    public static void main(String[] args) {
        int max = 1000000;
        List<String> values = new ArrayList<>(max);
        for (int i = 0; i < max; i++) {
            UUID uuid = UUID.randomUUID();
            values.add(uuid.toString());
        }

       /* System.out.println("----------串行------------");
        long t0 = System.currentTimeMillis();
        long count = values.stream().sorted().count();
        System.out.println(count);
        long t1 = System.currentTimeMillis();
        long millis = t1-t0;
        System.out.println(millis);*/

//        System.out.println("-------------并行----------------");
        long t0 = System.currentTimeMillis();
      //  parallelStream()是Collection接口的方法
        long count = values.parallelStream().sorted().count();
        System.out.println(count);
        long t1 = System.currentTimeMillis();
        long millis = t1-t0;
        System.out.println(millis);

    }
}

串行需要880ms,并行只需要450ms。

第四节:新时间?期API

Java 8通过发布新的Date-Time API (JSR 310)来进?步加强对?期与时间的处理。

在旧版的 Java 中,?期时间 API 存在诸多问题,其中有:

  • ?线程安全 ? java.util.Date 是?线程安全的,所有的?期类都是可变的,这是Java?期类最?的问题之?。
  • 设计很差 ? Java的?期/时间类的定义并不?致,在java.util和java.sql的包中都有?期类,此外?于格式化和解析的类在java.text包中定义。java.util.Date同时包含?期和时间,?java.sql.Date仅包含?期,将其纳?java.sql包并不合理。另外这两个类都有相同的名字,这本身就是?个?常糟糕的设计。
  • 时区处理麻烦 ? ?期类并不提供国际化,没有时区?持,因此Java引?了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。

Java 8 在 java.time 包下提供了很多新的 API。以下为两个?较重要的 API:

  • Local(本地) ? 简化了?期时间的处理,没有时区的问题。
  • ZoneId (时区) ? 通过定制的时区处理?期时间。

线程安全问题演示:

public class Test6 {
    public static void main(String[] args) throws  Exception {

        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        
        //创建线程操作
        Callable<LocalDate> task = new Callable<LocalDate>() {
            @Override
            public LocalDate call() throws Exception {
               // return simpleDateFormat.parse("20200301");
                return LocalDate.parse("20200301",formatter);
            }
        };
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        List<Future> list=new ArrayList<Future>();
        for(int i=0;i<10;i++){
            Future<LocalDate> submit = executorService.submit(task);
            list.add(submit);
        }
        //结果的输出
        for (Future future : list) {
            System.out.println(future.get());
        }
        //线程结束
        executorService.shutdown();

    }
}

在这里插入图片描述
使?新时间?期API解决

public class Test6 {
    public static void main(String[] args) throws  Exception {

        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyyMMdd");
        //创建线程操作
        Callable<LocalDate> task = new Callable<LocalDate>() {
            @Override
            public LocalDate call() throws Exception {
               // return simpleDateFormat.parse("20200301");
                return LocalDate.parse("20200301",formatter);
            }
        };
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        List<Future> list=new ArrayList<Future>();
        for(int i=0;i<10;i++){
            Future<LocalDate> submit = executorService.submit(task);
            list.add(submit);
        }
        //结果的输出
        for (Future future : list) {
            System.out.println(future.get());
        }
        //线程结束
        executorService.shutdown();
    }
}

4.1 本地化?期时间 API

LocalDate/LocalTime 和 LocalDateTime 类可以在处理时区不是必须的情况。

LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使? ISO-8601? 历系统的?期、时间、?期和时间。它们提供了简单的?期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。

public class Test7 {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        //指定时间
        LocalDateTime time = LocalDateTime.of(2020, 11, 20, 10, 20);
        System.out.println(time);
       //时间运算
        LocalDateTime localDateTime = time.plusDays(3);
        System.out.println(localDateTime);
        LocalDateTime localDateTime1 = time.minusHours(3);
        System.out.println(localDateTime1);
        //获得某个字段的信息
        System.out.println(now.getYear());
        System.out.println(now.getHour());
    }
}

4.2 Instant、ZoneId

Instant 时间戳

它是以Unix元年(传统 的设定为UTC时区1970年1?1?午夜时分)开始 所经历的描述进?运算

4.3 时间矫正器 TemporalAdjuster

TemporalAdjuster : 时间校正器。有时我们可能需要获 取例如:将?期调整到“下个周?”等操作。

TemporalAdjusters : 该类通过静态?法提供了?量的常 ? TemporalAdjuster 的实现。

4.4 DateTimeFormatter

java.time.format.DateTimeFormatter 类:该类提供了三种 格式化?法:

预定义的标准格式

语?环境相关的格式

?定义的格式

public class Test8 {
    public static void main(String[] args) {
       /* //时间戳
        Instant now = Instant.now();
        System.out.println(now);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Instant now2 = Instant.now();
        long millis = Duration.between(now, now2).toMillis();
        System.out.println(millis);

        //时区
        Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
        for (String availableZoneId : availableZoneIds) {
            System.out.println(availableZoneId);
        }
        ZoneId id = ZoneId.of("America/Shiprock");
        System.out.println(id.getRules());*/


        //未来时间的获取
        /*LocalDate now = LocalDate.now();
        LocalDate with = now.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
        System.out.println(with);*/

        //时间格式化
        LocalDate now = LocalDate.now();
        System.out.println(now);
        LocalTime now1 = LocalTime.now();
        System.out.println(now1);
        LocalDateTime now2 = LocalDateTime.now();
        System.out.println(now2);
        //date->String
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
        String format = formatter.format(now2);
        System.out.println(format);
        //String -date
        LocalDateTime parse = LocalDateTime.parse("20201212 12:02:35", formatter);
        System.out.println(parse);
    }
}

第五节: 接?中的默认?法和静态?法

在接?中可以使?default和static关键字来修饰接?中定义的普通?法

interface  A{
    public void abc();
    default void bcd(){
        System.out.println("bcd");
    }
    static void cc(){
        System.out.println("cccc");
    }
}
interface  B{
    public void abc();
}
public class Demo1  implements  B,A{
    @Override
    public void abc() {

    }

    public static void main(String[] args) {
        new Demo1().abc();
        new Demo1().bcd();
        A.cc();
    }
}

在JDK1.8中很多接?会新增?法,为了保证1.8向下兼容,1.7版本中的接?实现类不?每个都重新实现新添加的接??法,引?了default默认实现,static的?法是直接?接?名去调?法即可。当?个类继承?类?实现接?时,若后两者?法名相同,则优先继承?类中的同名?法,即“类优先”,如果实现两个同名?法的接?,则要求实现类必须?动声明默认实现哪个接?中的?法。

第六节: 对HashMap的优化

在jdk1.8中对hashMap等map集合的数据结构优化。hashMap数据结构的优化 。原来的hashMap采?的数据结构是哈希表(数组+链表),hashMap默认??是16,?个0-15索引的数组,如何往??存储元素,?先调?元素的hashcode ?法,计算出哈希码值,经过哈希算法算成数组的索引值,如果对应的索引处没有元素,直接存放,如果有对象在,那么?较它们的equals?法?较内容 如果内容?样,后?个value会将前?个value的值覆盖,如果不?样,在1.7的时候,后加的放在前?,形成?个链表,形成了碰撞,在某些情况下如果链表?限下去,那么效率极低,碰撞是避免不了的。

加载因?:0.75,数组扩容,达到总容量的75%,就进?扩容,但是?法避免碰撞的情况发?在1.8之后,在数组+链表+红?树来实现hashmap,当碰撞的元素个数?于8时 & 总容量?于64,会有红?树的引? 。除了添加之后,效率都?链表?。JDK1.7及之前的 ConcurrentHashMap 使? 锁分段机制 实现,JDK1.8则使? 数组+链表+红?树数据结构CAS原?操作实现。

jdk 7 与 jdk 8 中关于HashMap的对?

  • 8时红?树+链表+数组的形式,当桶内元素?于8时,便会树化
  • hash值的计算?式不同
  • 1.7 table在创建hashmap时分配空间,?1.8在put的时候分配,如果table为空,则为table分配空间。
  • 在发?冲突,插?链中时,7是头插法,8是尾插法。
  • 在resize操作中,7需要重新进?index的计算,?8不需要,通过判断相应的位是0还是1,要么依旧是原index,要么是oldCap + 原index。

第七节: Optional 类

Optional 类是?个可以为null的容器对象。如果值存在则isPresent()?法会返回true,调?get()?法会返回该对象。

Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有?的?法,这样我们就不?显式进?空值检测。

Optional 类的引?很好的解决空指针异常。

类中的?法

在这里插入图片描述
注意: 这些?法是从 java.lang.Object 类继承来的。

public class Test2 {
    public static void main(String[] args) {
        Integer a=null;
        Integer b=new Integer(20);
        Optional<Integer> a1 = Optional.of(b);//of()如果是null值,则报错NullPointerException
        Optional<Integer> a2 = Optional.ofNullable(b);//ofNullable
        System.out.println(a2);
        System.out.println(a2.isPresent());
        //获取数据
        Integer integer = a2.get();//非空数据时才能获取
        System.out.println(integer);

        System.out.println(a2.orElse(new Integer(30)));
    }
}

第?节: Base64

在Java 8中,Base64编码已经成为Java类库的标准。

Java 8 内置了 Base64 编码的编码器和解码器。

Base64?具类提供了?套静态?法获取下?三种BASE64编解码器:

  • 基本:输出被映射到?组字符A-Za-z0-9+/,编码不添加任何?标,输出的解码仅?持A-Za-z0-9+/。
  • URL:输出映射到?组字符A-Za-z0-9+_,输出是URL和?件。
  • MIME:输出隐射到MIME友好格式。输出每?不超过76字符,并且使?’\r’并跟随’\n’作为分割。编码输出最后没有?分割。

内嵌类

在这里插入图片描述
?法

在这里插入图片描述
注意:Base64 类的很多?法从 java.lang.Object 类继承。

public class Test3 {
    public static void main(String[] args) {
            //基本加密
        String str="yhp";
        //编码
        String s = Base64.getEncoder().encodeToString(str.getBytes());
        System.out.println(s);
        //解码
        byte[] decode = Base64.getDecoder().decode(s);
        System.out.println("解码:"+new String(decode));
    }
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:23:29  更:2021-11-09 19:25:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 13:59:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码