【Java SE】JDK 8 新特性 包括 Lambda

Java 8
——————————————————————————————————

Lambda表达式

  • 提问:为什么要用Lambda表达式?

是一个匿名函数,可以把它理解成一段可以传递的代码(把代码像数据一样进行传递);
更简洁、更灵活、更紧凑,让Java的语言表达能力得到了提升;
—————————————————

新特征:-> Kambda表达符/箭头表达符

(左)参数列表 -> (右)执行功能/Lambda体;

————————————
格式一:无参,无返回值;
() -> System.out.println("Hello Lambda");

BEFORE

Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello World!");
    }
};
r.run();

AFTER

Runnable r1 = () -> System.out.println("Hello Lambda!");
r1.run();

————————————

BEFORE

——————————————————————————————————
输出:

AFTER

——————————————————————————————————
输出:

————————————
格式二:有一个参数,无返回值;
(x) -> System.out.println(x)

Consumer<String> con = (x) -> System.out.println(x);
con.accept("Hahaha");

输出:
Hahaha

在这里插入图片描述
————————————
格式三:只有一个参数时,小括号可以不写;
x -> System.out.println(x)

(个人感觉通常还是加括号)
在这里插入图片描述
————————————
格式四:有两个以上的参数,有返回值,且Lambda体中有多条语句(多条就必须用花括号);

Comparator<Integer> com = (x,y) -> {
    System.out.println("Hahaha");
    return Integer.compare(x,y);
};

————————————
格式五:若Lambda体只有一条语句,return和花括号都可以省略;

Comparator<Integer> com = (x,y) -> return Integer.compare(x,y);

————————————
格式六:Lambda参数列表的数据类型可以不写,因为JVM会根据上下文「类型推断」

————————————
————————————
————————————
————————————
————————————
————————————
————————————
————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————

——————————————————————————————————

函数式接口

https://www.bilibili.com/video/av62117143/?p=3
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————

——————————————————————————————————

方法引用和构造器引用

—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————

——————————————————————————————————

Stream API

Java8最重要的两大改变就是Lambda和Stream API;

Stream API必须有三个部分:
1.创建 没有创建不会有输出
2.中间 (只有中间操作,不会有任何操作;必须有终止触发,才有输出,这个特性叫做惰性求值)
3.终止 stream.forEach() 没有终止就不会有输出;

stream.forEach()叫内部迭代,不归我们管,由Stream管
迭代器叫外部迭代;

—————————————————

筛选和切片

filter
limit
skip
distinct(使用时,实体类必须重写equals和hashCode)

—————————————————
.filter()

User类有两个属性:name和number;

new User("Aaron",100),
new User("Ben",237),
new User("Colen",122),
new User("Dylen",5),
new User("Eason",412)

Stream<User> stream = users.stream()
        .filter((e) -> e.getNumber() > 200);
stream.forEach(System.out::println);

——————————————————————————————————
输出:
User(name=Ben, number=237)
User(name=Eason, number=412)

—————————————————
.limit()

users.stream()
        .filter((e) -> e.getNumber() > 100)
        .limit(2)
        .forEach(System.out::println);
——————————————————————————————————
输出:
User(name=Ben, number=237)
User(name=Colen, number=122)        

可以看出来,limit用的排序顺序就是集合的定义顺序(从左到右);
从哪边截取数字?从左到右截取数字;

—————————————————
.skip(数字)
跳过前面几个Value;

users.stream()
        .filter((e) -> e.getNumber() > 100)
        .skip(2)
        .forEach(System.out::println);
——————————————————————————————————
输出:
User(name=Eason, number=412)

—————————————————
.distinct() 去重
实体类必须重写hashCode()equals();(@Data搞定)

List<User> users = Arrays.asList(
        new User("Aaron",100),
        new User("Ben",237),
        new User("Colen",122),
        new User("Dylen",5),
        new User("Eason",412),
        new User("Eason",412),
        new User("Eason",412)
);

users.stream()
        .filter((e) -> e.getNumber() > 100)
        .distinct()
        .forEach(System.out::println);

——————————————————————————————————
输出:
User(name=Ben, number=237)
User(name=Colen, number=122)
User(name=Eason, number=412)

—————————————————

映射(常用)

map
flatMap

—————————————————
.map()

List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");

list.stream()
        .map((str) -> str.toUpperCase())
        .forEach(System.out::println);
——————————————————————————————————
输出:
AAA
BBB
CCC
DDD
EEE

—————————————————
flatMap()


——————————————————————————————————
输出:

—————————————————

查找和匹配

—————————————————

归纳

—————————————————

收集

—————————————————
—————————————————
—————————————————

——————————————————————————————————

接口中的默认方法和静态方法

—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————

——————————————————————————————————

新时间日期API

—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————

——————————————————————————————————

其他

—————————————————

—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————
—————————————————

——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————
——————————————————————————————————

以下作废

——————————————————————————————————

Function / BiFunction 接口

———————————————————————

Function<T, R>

接口填两个范型:<输入参数,输出参数>
即:只接受一个输入参数;
实例方法.apply()计算结果;

用 Function 计算:9*9

import java.util.function.Function;
———————————————————————
Function<Integer,Integer> fun = arg -> arg*arg;
Integer apply = fun.apply(9);
System.out.println(apply);

———————————————————————
输出:
81

———————————————————————

BiFunction<T, U, R>

接口填三个范型:<输入参数,输入参数,输出参数>
即:接受两个输入参数;
(BiFunction是Function的升级版)
实例方法.apply()计算结果;

用 BiFunction 计算:10+20

import java.util.function.BiFunction;
———————————————————————
BiFunction<Integer,Integer,Integer> fun2 = (arg1,arg2) -> arg1+arg2;
Integer sum = fun2.apply(10,20);
System.out.println(sum);
———————————————————————
输出:30

——————————————————————————————————

map.putIfAbsent()

作用:代替map.put()
使用传统的.put()时,遇到key相同的情况时可能产生value覆盖;.putIfAbsent()可以解决此问题:key相同时不覆盖原value,只在key为NULL或不存在时才覆盖value值;

Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");

map.put(1,"new");

map.forEach((k,v) ->{
    System.out.println("k:"+k+" v:"+v);
});
———————————————————————
输出:
k:1 v:new
k:2 v:b
k:3 v:c
Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");

map.putIfAbsent(1,"new");

map.forEach((k,v) ->{
    System.out.println("k:"+k+" v:"+v);
});
———————————————————————
输出:
k:1 v:a
k:2 v:b
k:3 v:c

map.compute()

有空指针危险;

map.computeIfAbsent()

.computeIfAbsent().putIfAbsent()类似,

Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");

map.computeIfAbsent(1,key -> "new"+" value");

map.forEach((k,v) ->{
    System.out.println("k:"+k+" v:"+v);
});
———————————————————————
输出:
k:1 v:a
k:2 v:b
k:3 v:c
Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");

map.computeIfAbsent(9,key -> "new"+" value");

map.forEach((k,v) ->{
    System.out.println("k:"+k+" v:"+v);
});
———————————————————————
输出:
k:1 v:a
k:2 v:b
k:3 v:c
k:9 v:new value

———————————————————————
输出:

————————————
————————————
————————————
————————————
————————————
————————————
————————————
————————————
——————————————————————————————————

map.computeIfPresent()

——————————————————————————————————

Function 接口

——————————————————————————————————

Supplier 接口

package java.util.function;

/**
 * Represents a supplier of results.
 *
 * <p>There is no requirement that a new or distinct result be returned each
 * time the supplier is invoked.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #get()}.
 *
 * @param <T> the type of results supplied by this supplier
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

————————————

  • 提问:Supplier和传统的 new 创建对象有什么区别?

————————————
有参构造器:

Entity:Ppl

@Data
@AllArgsConstructor
public class Ppl {
    private String name;
    private Integer age;
}

未使用 Supplier 时(JDK8之前)

@RestController
public class MyController {
    public static void main(String[] args) {

        Ppl ppl1 = new Ppl("tom",20);
        Ppl ppl2 = new Ppl("Mary",20);
        System.out.println(ppl1);
        System.out.println(ppl2);
    }
}
———————————————————————
输出:
Ppl(name=tom, age=20)
Ppl(name=Mary, age=20)

使用 Supplier 时(JDK8)

?

————————————

?
?
?

————————————
————————————
————————————
————————————
————————————
————————————
——————————————————————————————————

易错总结

1.filter中:是->,不是-->,否则报错;
https://www.runoob.com/java/java8-streams.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值