JAVA8 新特性


前言

随着代码的简化,高效的提升。今天我也来做一次总结。慢慢积累,来年硕果累累。


首先要学习新特性的话,我们就要先了解什么是函数式接口

  1. Predicate boolean test(T t); 判断型:传入T返回Boolean
  2. Consumer void accept(T t); 消费型:传入T无返回值
  3. Supplier T get(); 供给型:无需传值就能获取数据
  4. Function R apply(T t); 消费型供给型结合体:传入T返回R

一、JAVA8 主要引入了什么?

  1. Lambda表达式
  2. 方法引用
  3. Stream API
  4. Date Time API
  5. Optional 类

1.Lambda表达式使用案例

代码如下(示例):

List<String> userNames = userList.stream().map(e -> e.getUserName()).collect(Collectors.toCollection(ArrayList::new));

使用lambda的标识就是 ()加 -> 就能使用了。如果是一个参数的话,可以像上面的一样不用使用括号包裹起来。

2.方法引用

代码如下(示例):

List<String> userNames = userList.stream().map(User::getUserName).collect(Collectors.toCollection(ArrayList::new));

由此可见方法的引用就使代码更加的简洁了,可以看上面的案例。

3.Stream API

代码如下(示例):
如下是单线程流处理

List<String> userNames = userList.stream().map(User::getUserName).collect(Collectors.toCollection(ArrayList::new));

如下是并行流处理

List<String> userNames = userList.parallelStream().map(User::getUserName).collect(Collectors.toCollection(ArrayList::new));

由此可见方法的引用就使代码更加的简洁了,可以看上面的案例。

4.Date Time API

1.时间API,保证了线程安全问题。

代码如下(示例):

ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.parse("2021-01-29 10:51:25", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ZoneId.of("Asia/Shanghai"));

大伙儿,可以直接拷贝代码进行使用,只需要将时间字符串动态传递即可,同时也可以手动设置时区。

2.Temporal 时间接口
3.Duration 对象(被final修饰了)。

5.Optional 类

这个类的功能就强大了,有两种方式。用来处理我们最常见的NullPointerException异常。
代码如下(示例):

UserBean userBean = Optional.ofNullable(user).orElse(new UserBean());
UserBean userBean = Optional.ofNullable(user).orElseGet(() -> new UserBean());

这样我们就不会出现空指针异常了。

二、创建实例

package com.hh.userservice;

import lombok.Data;

import java.io.Serializable;

@Data
public class User implements Serializable,Cloneable {

    private String userName;
    private Integer userAge;

    public User(String userName, Integer userAge) {
        this.userName = userName;
        this.userAge = userAge;
    }

    public User(){
    }

    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return clone;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getUserAge() {
        return userAge;
    }

    public void setUserAge(Integer userAge) {
        this.userAge = userAge;
    }

}

三、积累常用案例

List<String> arrayList1 = new ArrayList<>();
arrayList1.add("1");
arrayList1.add("2");
arrayList1.add("3");
List<String> arrayList2 = new ArrayList<>();
arrayList2.add("2");
arrayList2.add("4");

1.两(N)个集合,获取交集功能

第一种方式,通过流中的过滤器,加上集合内部的方法引用。

List<String> stringArrayList = arrayList1.stream().filter(arrayList2::contains).collect(Collectors.toCollection(ArrayList::new));

第二种方式,更加高级一点,扁平化处理集合,加上流中的过滤功能。

List<String> collect = Stream.of(arrayList1, arrayList2).flatMap(Collection::stream).distinct().collect(Collectors.toCollection(ArrayList::new));

第三种方式,通过集合中的retainAll方法实现(切记有坑哦)。
如下代码执行后,切记只能获取arrayList1中的集合,因为arrayList2集合的数据不会变,不会被移除。

System.out.println(arrayList1);  // [1, 2, 3]
System.out.println(arrayList2);[2, 3]
boolean b = arrayList1.retainAll(arrayList2);
System.out.println(b);  // true
System.out.println(arrayList1);  // [2, 3]
System.out.println(arrayList2);  // [2, 3]

如下代码执行后可以随意获取那个集合中的数据。

boolean b1 = arrayList1.retainAll(arrayList2);
boolean b2 = arrayList2.retainAll(arrayList1);

如下源码:

public boolean retainAll(Collection<?> c) {
        Objects.requireNonNull(c);
        return batchRemove(c, true);
    }

    private boolean batchRemove(Collection<?> c, boolean complement) {
        final Object[] elementData = this.elementData;
        int r = 0, w = 0;
        boolean modified = false;
        try {
            for (; r < size; r++)
                if (c.contains(elementData[r]) == complement)
                    elementData[w++] = elementData[r];
        } finally {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            if (r != size) {
                System.arraycopy(elementData, r,
                                 elementData, w,
                                 size - r);
                w += size - r;
            }
            if (w != size) {
                // clear to let GC do its work
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }

2.两(N)个集合,获取差集功能

List<String> array1 = arrayList1.stream().filter(e -> !arrayList2.contains(e)).collect(Collectors.toCollection(ArrayList::new));
//        arrayList.forEach(System.out::println);
List<String> array2 = arrayList2.stream().filter(e -> !arrayList1.contains(e)).collect(Collectors.toCollection(ArrayList::new));
strings.forEach(System.out::println);   //结果:4  注意:获取的值是当前arrayList2集合的差集。arrayList1集合内的数据不会被加载。
List<String> newList = Stream.of(array1, array2).flatMap(Collection::stream).distinct().collect(Collectors.toCollection(ArrayList::new));

3.两(N)个集合,获取并集功能

List<String> arrayList = Stream.of(arrayList1, arrayList2).flatMap(Collection::stream).distinct().collect(Collectors.toCollection(ArrayList::new));
System.out.println(arrayList); //结果: [1, 2, 3, 4]

4.使用toMap需要注意的

1.在这边通过Collectors工具类,将流中的数据收集,将数据转换成功Map类型的数据。在这边我需要强调一下,首先我们这里有三个参数,第一个参数也就是Map的Key,第二个参数是我们的Value,第三个参数最为重要,(如果相同的话就会报错,如果没有报错的话确实没有任何问题的),表示如果Key相同的话,会将老的数据返回,新的Key被覆盖。
List<User> userList = getUserList();
Map<String, Integer> map = userList.stream().collect(Collectors.toMap(User::getUserName, User::getUserAge, (oldValue, newValue) -> oldValue));

5.Lamdba遍历Map集合的一种方式

1.高大上,比entrySet(),keySet()方式简洁,但是本质上还是enterSet()方式遍历的。
map.forEach((key, value) -> {
	System.out.print(key);
	System.out.print(value);
	System.out.println();
});

6.sorted方法内的比较器Comparator使用案例

1.使用比较器的方式对集合进行排序。代码非常的简洁明了。
List<User> collect1 = userList1.parallelStream().sorted(Comparator.comparing(User::getUserAge)).collect(Collectors.toCollection(ArrayList::new));
2.使用比较器中的reversed() 方法实现数组数据反转功能。
List<User> collect2 = userList1.parallelStream().sorted(Comparator.comparing(User::getUserAge).reversed()).collect(Collectors.toCollection(ArrayList::new));
3.使用一个比较冷门的方法Comparator.nullsFirst() 用来处理空对象,防止NPE。
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan",19));
userList.add(new User("lisi",39));
userList.add(new User("wangwu",26));
userList.add(new User("maliu",26));
userList.add(new User("maliu",26));
userList.add(null);
List<User> collect = userList.parallelStream().sorted(Comparator.nullsFirst(Comparator.comparing(User::getUserAge))).collect(Collectors.toCollection(ArrayList::new));
4.使用比较器实现多个字段进行比较方式。(链式编程之thenComparing()方法)
List<User> collect3 = userList1.parallelStream().sorted(Comparator.comparing(User::getUserName).thenComparing(User::getUserAge)).collect(Collectors.toCollection(ArrayList::new));

总结

简单,是一种态度。不争,顺其自然,不求,一切随缘,不气,心胸开阔,不怨,心怀感激。放下计较矛盾,轻松地活;看淡金钱财富,知足地过。远离是是非非,不理流言蜚语。简单的人生,简单地活;简单的日子,简单地过。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉忆-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值