lambda
简单记录一下学习的内容,不是很深入
基础语法
左侧:lambda 表达式的参数列表
右侧:lambda 表达式中所需要执行的功能,即lambda体
语法格式一:接口中的抽象方法,无参数,无返回值
()->System.out.println("hello lambda")
语法格式二:一个参数,并且无返回值
(x) -> System.out.println(x)
语法格式三:若只有一个参数,小括号可以不写
x -> System.out.println(x)
语法格式四:有两个以上的参数,有返回值,并且lambda体中有多条语句
Comparator<Integer> com = (x,y)->{
System.out.println("函数式接口");
return Integer.compare(x,y);
};
语法格式五:若lambda体中只有一条语句有参数,和返回值,大括号可以省略,return也可以省略
Comparator<Integer> com = (x,y)->Integer.compare(x,y);
语法格式六:lambda表达式的参数列表的参数类型可以省略不写,因为jvm可以根据上下文推断出数据类型
(Integer.x,Integer.y) -> Integer.compare(x,y)
巧记总结
左侧推断类型省
能省就省
函数式接口
lambda表达式需要“函数式接口”的支持
接口中只有一个抽象方法的接口,称为函数式接口。可以使用@FunctionalInterface注解(方便编译器检查识别)
default和static方法均不是抽象方法
Java 8 四大核心函数式接口
Consumer接口
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
void accept(),实现该方法进行消费,消费的内容由传入的泛型决定
andThen(),个人理解为可以进行连续消费,当前这次消费逻辑accept()完成后,然后再进行下一次消费逻辑after.accept()
// 消费
public void test04(){
Consumer<Double> consumer = money ->{
money -= 100;
System.out.println("您当前余额为"+money);
};
consumer.accept(1000.0);
}
Supplier 接口
@FunctionalInterface
public interface Supplier<T> {
T get();
}
T get(),实现该方法得到一个对象数据
// 需求:得到一个随机数数组
public void test03(){
Supplier<Integer> supplier = () -> (int)(Math.random()*100);
List<Integer> ret = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ret.add(supplier.get());
}
// 遍历输出测试
}
Function<T,R>:函数型接口,T为参数,R为返回值
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
函数式接口,个人理解就是从一个值映射到另一个值,这两个值的类型没有要求,从Integer-->Intger或者Integer --> Object 都可以
R apply(T t) 实现该方法,方法内部就是你要完成的映射逻辑
compose() 先执行传入的before.apply(),再执行当前的apply(before.apply())
andThen() 和之前的函数式接口方法中的andThen()类似,就是接下来怎么做,先执行当前的映射然后怎么做,可以继续映射(执行传入的逻辑)
andThen()和compose() 区别:
andThen:先执行当前函数接口实现的apply逻辑,再执行传入的after.apply()逻辑
compose:先执行传入的before.apply()逻辑,再执行当前函数接口实现的apply()逻辑
//需求:处理字符串 也就是将原来的值映射为另一个值
public void test02(){
Function<String,String> process = str -> str.toLowerCase();
String abde = process.apply("ABDE");
Function<String,String> process2 = str -> str.trim();
String apply = process2.apply(" abcd e ");
}
Predicate : 断言型接口
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {return (t) -> !test(t);}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
static <T> Predicate<T> not(Predicate<? super T> target) {
Objects.requireNonNull(target);
return (Predicate<T>)target.negate();
}
}
Predicate接口与Function接口很像,只不过其是将当前传入的参数映射(按照实现的逻辑)到true或者false
and() 将传入的数据与处理逻辑中用到的某个 参数进行 and 返回true 或false
or()
negate()
也就是 & | !
isEqual() 判断是否相等
同样这些操作可以连续执行,先and() 再 negate() ....
//需求:将满足条件的字符串,装入集合中
public List<String> filterStr(List<String> list,Predicate<String> predict){
List<String> ret = new ArrayList<>();
for (String s : list) {
if(predict.test(s)){
ret.add(s);
}
}
return ret;
}
public void test01(){
List<String> list = Arrays.asList("hello","atguigu","lambda","www","ok");
filterStr(list,str->str.length()>3);
// 遍历输出 产看结果
list.forEach(str - System.out.println(str))
}
这些函数式接口大多数都可以进行链式执行(函数式编程),先这样,再这样,再这样....
下一篇内容关于 lambda应用— Stream