失去人性,失去很多;失去兽性,失去一切。——《三体》
在Java8支持Lambda表达式以后,为了满足Lambda表达式的一些典型使用场景,JDK为我们提供了大量常用的函数式3,接口。它们主要在javutifunction包中,下面简单介绍几个其中的3,接口及其使用示例。
Supplier3,接口
Supplier3,接口是对象实例的提供者,定义了一个名叫get的抽象方法,它没有任何入参,并返回一个泛型T对象,具体源码如下:
package java.util.function;
@FunctionalInterface
public interface Supplier {
T get();
}
源码比较简单,我们来个例子。这是之前提过的表示口罩的类:
package one.more.study;
/**
* 口罩
*/
public class Mask {
public Mask(String brand, String type) {
this.brand = brand;
this.type = type;
}
/**
* 品牌
*/
private String brand;
/**
* 类型
*/
private String type;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
下面我们使用Lambda表达式声明一个Supplier的实例:
Supplier supplier = () -> new Mask('3M', 'N95');
用它来创建品牌为3M、类型为N95的Mask实例:
Mask mask = supplier.get();
System.out.println('Brand: ' + mask.getBrand() + ', Type: ' + mask.getType());
运行结果如下:
特别需要注意的是,本例中每一次调用get方法都会创建新的对象。
Consumer3,接口
Consumer3,接口是一个类似消费者的3,接口,定义了一个名叫accept的抽象方法,它的入参是一个泛型T对象,没有任何返回,主要源码如下:
package java.util.function;
@FunctionalInterface
public interface Consumer {
void accept(T t);
}
结合上面的Supplier3,接口,我们来个例子:
Supplier supplier = () -> new Mask('3M', 'N95');
Consumer consumer = (Mask mask) -> {
System.out.println('Brand: ' + mask.getBrand() + ', Type: ' + mask.getType());
};
consumer.accept(supplier.get());
首先使用Lambda表达式声明一个Supplier的实例,它是用来创建品牌为3M、类型为N95的Mask实例;再使用Lambda表达式声明一个Consumer的实例,它是用于打印出Mask实例的相关信息;最后Consumer消费了Supplier生产的Mask。运行结果如下:
Predicate3,接口是判断是与否的3,接口,定义了一个名叫test的抽象方法,它的入参是一个泛型T对象,并返回一个boolean类型,主要源码如下:
package java.util.function;
@FunctionalInterface
public interface Predicate {
boolean test(T t);
}
结合上面的Supplier3,接口,我们来个例子:
Supplier supplier = () -> new Mask('3M', 'N95');
Predicate n95 = (Mask mask) -> 'N95'.equals(mask.getType());
Predicate kn95 = (Mask mask) -> 'KN95'.equals(mask.getType());
System.out.println('是否为N95口罩:' + n95.test(supplier.get()));
System.out.println('是否为KN95口罩:' + kn95.test(supplier.get()));
首先使用Lambda表达式声明一个Supplier的实例,它是用来创建品牌为3M、类型为N95的Mask实例;再使用Lambda表达式声明一个Predicate的实例n9它是用于判断是否为N95口罩;再使用Lambda表达式声明一个Predicate的实例kn9它是用于判断是否为KN95口罩;最后分别用两个Predicate判断Supplier生产的Mask。运行结果如下:
是否为N95口罩:true
是否为KN95口罩:false
Function3,接口
Function3,接口是对实例进行处理转换的3,接口,定义了一个名叫apply的抽象方法,它的入参是一个泛型T对象,并返回一个泛型R对象,主要源码如下:
package java.util.function;
@FunctionalInterface
public interface Function {
R apply(T t);
}
结合上面的Supplier3,接口,我们来个例子:
Supplier supplier = () -> new Mask('3M', 'N95');
Function brand = (Mask mask) -> mask.getBrand();
Function type = (Mask mask) -> mask.getType();
System.out.println('口罩品牌:' + brand.apply(supplier.get()));
System.out.println('口罩类型:' + type.apply(supplier.get()));
首先使用Lambda表达式声明一个Supplier的实例,它是用来创建品牌为3M、类型为N95的Mask实例;再使用Lambda表达式声明一个Function的实例brand,它是用于获取口罩的品牌;再使用Lambda表达式声明一个Function的实例type,它是用于获取口罩的类型;最后分别用两个Function分析Supplier生产的Mask。运行结果如下:
口罩品牌:3M
口罩类型:N95
Function3,接口的入参只有一个泛型对象,JDK还为我们提供了两个泛型对象入参的3,接口:BiFunction3,接口,主要源码如下:
package java.util.function;
@FunctionalInterface
public interface BiFunction {
R apply(T t, U u);
}
我们可以用BiFunction3,接口传入两个String直接创建Mask实例:
BiFunction biFunction = (String brand, String type) -> new Mask(brand, type);
Mask mask = biFunction.apply('3M', 'N95');
System.out.println('Brand: ' + mask.getBrand() + ', Type: ' + mask.getType());
运行结果如下:
基本数据类型
以上介绍的几个常用的函数式3,接口入参和返回,都是泛型对象的,也就是必须为引用类型。当我们传入或获取的是基本数据类型时,将会发生自动装箱和自动拆箱,带来不必要的性能损耗,比如:
Supplier supplier = () -> System.currentTimeMillis();
long timeMillis = supplier.get();
在上面例子里,发生了一次自动装箱和一次自动拆箱,如何避免这种不必要的性能损耗呢?JDK为我们提供相应的函数式3,接口,如LongSupplier3,接口,定义了一个名叫getAsLong的抽象方法,签名是()->long。上面的例子可以优化为:
LongSupplier supplier = () -> System.currentTimeMillis();
long timeMillis = supplier.getAsLong();
类似这样的3,接口还有很多,我为大家整理了一下:
Supplier相关的3,接口
Supplier | get | () -> T |
BooleanSupplier | getAsBoolean | () -> boolean |
DoubleSupplier | getAsDouble | () -> double |
IntSupplier | getAsInt | () -> int |
LongSupplier | getAsLong | () -> long |
Consumer相关的3,接口
Consumer | accept | (T) -> void |
DoubleConsumer | accept | (double) -> void |
IntConsumer | accept | (int) -> void |
LongConsumer | accept | (long) -> void |
ObjDoubleConsumer | accept | (T, double) -> void |
ObjIntConsumer | accept | (T, int) -> void |
ObjLongConsumer | accept | (T, long) -> void |
Predicate相关的3,接口
Predicate | test | (T) -> boolean |
BiPredicate | test | (T, U) -> boolean |
DoublePredicate | test | (double) -> boolean |
IntPredicate | test | (int) -> boolean |
LongPredicate | test | (long) -> boolean |
Function相关的3,接口
Function | apply | (T) -> R |
BiFunction | apply | (T, U) -> R |
DoubleFunction | apply | (double) -> R |
DoubleToIntFunction | applyAsInt | (double) -> int |
DoubleToLongFunction | applyAsLong | (double) -> long |
IntFunction | apply | (int) -> R |
IntToDoubleFunction | applyAsDouble | (int) -> double |
IntToLongFunction | applyAsLong | (int) -> long |
LongFunction | apply | (long) -> R |
LongToDoubleFunction | applyAsDouble | (long) -> double |
LongToIntFunction | applyAsInt | (long) -> int |
ToDoubleFunction | applyAsDouble | (T) -> double |
ToDoubleBiFunction | applyAsDouble | (T, U) -> double |
ToIntFunction | applyAsInt | (T) -> int |
ToIntBiFunction | applyAsInt | (T, U) -> int |
ToLongFunction | applyAsLong | (T) -> long |
ToLongBiFunction | applyAsLong | (T, U) -> long |
死磕Lambda表达式:初识Lambda死磕Lambda表达式:Lambda的使用死磕Lambda表达式:更简洁的Lambda死磕Lambda表达式:常用的函数式3,接口死磕Lambda表达式:Comparator复合死磕Lambda表达式:Consumer、Predicate、Function复合
文章持续更新,微信搜索「万猫学社」第一时间阅读。
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点
BOSS2022-05-13
盘面符合预判,今天冲高如期创出本周新高,同步突破3050点反压以后,日线级别出现昨天早盘2957点以来第一个分时线高点反压,虽然级别不大,但日线级别不激进了,手中股票学会区别对待,或动静不大盯紧拿好;或明显放量异动尤其浮盈的,注意波段高抛或止盈!千万不要昨天低位机会不敢低吸,现在却要去追涨了,这是不合理的!明白的点赞“777”!小v2022-04-27
哈哈,我在梦里,那你面对现实了吗?欧洲也没清零最近股票好了还是怎么?股票下跌都是一种因素导致的是吗?放开了就保增长了?缘份的天空2022-04-26
大盘还真得有九安这样的重量级带头拉升,才有救。如果连九安这么好的公司都跌,那谁有资格带动大a,指望那几个骗子股票公司吗。