目录
一.什么是Lambda表达式
二.语法格式
三.Lambda表达式使用
1.从匿名类到Lambda的转化
2.匿名内部类作为参数传递
3.函数式接口
4.作为参数传递Lambda表达式
5.方法引用
6.构造器引用
7.数组引用
四.Stream流
1.什么是Stream流
2.Stream流特点
3.操作步骤
4.创建流的例子
5.Stream流的中间操作
6.Stream流的终止操作
Lambda 是一个匿名函数,可以将其理解为是一段可以传递的代码,或者说是将代码像数据一样进行传递。使用Lambda表达式可以写出更简洁、更灵活的代码。它作为一种更紧凑的代码风格,使 Java的语言表达能力得到了提升。
Lambda 表达式在Java 语言中引入了一个新的语法元 素和操作符 “->” , 该操作符被称 为 Lambda 操作符或箭头操作符。它将 Lambda 分为 两个部分:
1.无参,无返回值
Runnable runnable = ()-> System.out.println("hello");
2.需要一个参数来传值
ConsumerstringConsumer = args-> System.out.println(args);
3.需要两个参数---代码块,代码块中只有return一条语句时,大括号{}可省略
//多语句时
BinaryOperatorbinaryOperator = (x,y)->{
System.out.println("hahaha");
return x+y;
};
//只有返回语句时
BinaryOperatorbinaryOperator1 = (x,y)->x+y;
//lambda表达式的类型是由编译器根据上下环境推断出来的,一般来说不用自己编写数据类型
直接上对比代码和图:
//原来创建Runnable的操作
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println("runnable1:hello world");
}
};
runnable1.run();
//Lambda
Runnable runnable2 = ()-> System.out.println("runnable2:hello world");
runnable2.run();
//原来使用匿名内部类作为参数传递
TreeSet ts = new TreeSet<>(new Comparator() {
@Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(),o2.length());
}
});
//lambda1
TreeSetts2 = new TreeSet<>(
((o1, o2) -> Integer.compare(o1.length(),o2.length()))
);
//lambda2(更简单版)
TreeSetts2 = new TreeSet<>(
(Comparator.comparingInt(String::length))
);
函数式接口:只包含一个抽象方法的接口称为函数式接口。
public interface getage{
public int getvalue();
}
也可以在任意函数式接口上使用@FunctionalInterface注解标明,这样可以检查其函数式接口的正确性,同时也会在javadoc中生成一条说明,说明这个接口是一个函数式接口。
@FunctionalInterface
public interface getage{
public int getvalue();
}
@FunctionalInterface
public interface GetName{
public T getValue(T t);
}
public String toUpperString(GetNamegetName,String name){
return getName.getValue(name);
}
@Test
public void test(){
String string = toUpperString(str->str.toUpperCase(),"xiaolizi");
System.out.println(string);
}
(x)-> System.out.println(x);
等价于
System.out::println;
BinaryOperator binaryOperator = (x,y)->Math.pow(x,y);
等价于
BinaryOperator binaryOperator = Math::pow;
compare((x,y) -> x.equals(y),"abcdf","abcdf");
等价于
compare(String::equals,"abcdf","abcdf");
与函数式接口相结合,自动与函数式接口中方法兼容。 可以把构造器引用赋值给定义的方法,与构造器参数 列表要与接口中抽象方法的参数列表一致!
Functionfunction = n->new MyClass(n);
等价于
Functionfunction = MyClass::new;
这里的MyClass是一个函数式接口,请自行定义
Functionfunction = n -> new Integer[];
等价于
Functionfunction = Integer[]::new;
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对 集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。 使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数 据库查询。也可以使用 Stream API 来并行执行操作。简而言之, Stream API 提供了一种高效且易于使用的处理数据的方式。
Stream流是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
1.由数组创建
2.由值创建
对象.stream().中间操作.终止操作;
假设我现在有一个Apple类,里面存放了苹果的颜色和重量
package Apple分类;
public class Apple {
private String color;
private float weight;
public Apple(String color, float weight){
this.color = color;
this.weight =weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
//这个toString不写的话会乱码的
@Override
public String toString() {
return "Apple [" +
"color='" + color + '\'' +
", weight=" + weight +
']';
}
//后面两个暂时用于去重
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Apple apple = (Apple) o;
return Float.compare(apple.weight, weight) == 0 &&
Objects.equals(color, apple.color);
}
@Override
public int hashCode() {
return Objects.hash(color, weight);
}
}
然后我现在有这些苹果
package Apple分类;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AppleMain {
public static void main(String[] args) {
//我的苹果
List apples = Arrays.asList(
new Apple("yello",150),
new Apple("green",50),
new Apple("red",100),
new Apple("yello",100),
new Apple("green",150),
new Apple("red",50),
new Apple("green",110),
new Apple("green",90),
new Apple("green",70),
new Apple("red",110),
new Apple("yello",50),
new Apple("green",200),
new Apple("red",150),
new Apple("red",70),
new Apple("red",70),
new Apple("red",70)
);
}
}
现在,我要挑选绿色的苹果
apples.stream().filter(a -> a.getColor().equals("green")).forEach(System.out::println);
我现在不要绿苹果了,我想看看重量超过100的苹果有哪些
apples.stream().filter(a -> a.getWeight()>100).forEach(System.out::println);
那么,重量大于100且为绿色的苹果有哪些呢?
apples.stream().filter(a -> a.getWeight()>100).filter(a->a.getColor().equals("green")).forEach(System.out::println);
现在,我想知道有多少种不同重量且不同颜色的苹果(去除重复项)
apples.stream().distinct().forEach(System.out::println);
苹果顺序有点乱,我想按颜色排序看看
apples.stream().sorted(Comparator.comparing(Apple::getColor)).forEach(System.out::println);
那按重量排序呢?
apples.stream().sorted(Comparator.comparing(Apple::getWeight)).forEach(System.out::println);
那么按颜色排序的同时按重量排序呢?
apples.stream().sorted(Comparator.comparing(Apple::getWeight)).sorted(Comparator.comparing(Apple::getColor)).forEach(System.out::println);
重量逆序呢?
apples.stream().sorted(Comparator.comparing(Apple::getWeight).reversed()).sorted(Comparator.comparing(Apple::getColor)).forEach(System.out::println);
上面的排序之后的苹果太多了,我只要前5个
apples.stream().sorted(Comparator.comparing(Apple::getWeight).reversed()).sorted(Comparator.comparing(Apple::getColor)).limit(5).forEach(System.out::println);
现在,我只想要前五个中的后两个,前三个苹果不要,我想跳过
apples.stream()
.sorted(Comparator.comparing(Apple::getWeight).reversed())
.sorted(Comparator.comparing(Apple::getColor))
.limit(5)
.skip(3)
.forEach(System.out::println);
突然之间,我又想知道有多少种颜色的苹果了,但是我不想知道他们的重量
apples.stream()
.map(Apple::getColor)
.distinct()
.forEach(System.out::println);
我想知道的是他们大写的样子
apples.stream()
.map(Apple::getColor)
.map(String::toUpperCase)
.distinct()
.forEach(System.out::println);
以下操作因为都是终止操作,所以需要先赋值,再输出。
Boolean b = apples.stream().anyMatch(a->a.getColor().equals("green"));
System.out.println("green苹果存在? "+b);
Boolean o = apples.stream().anyMatch(a->a.getColor().equals("orange"));
System.out.println("orange苹果存在? "+o);
Boolean g = apples.stream().allMatch(a->a.getColor().equals("green"));
System.out.println(g);
Boolean g = apples.stream().noneMatch(a->a.getColor().equals("green"));
System.out.println(g);
Boolean b = apples.stream().noneMatch(a->a.getColor().equals("black"));
System.out.println(b);
Optional a = apples.stream().findFirst();
System.out.println(a);
Optionalb = apples.stream().findAny();
System.out.println(b);
//找元素一般是从第一个元素开始
long count = apples.stream().count();
System.out.println(count);
Optional optionalApple = apples.stream()
.map(a->a.getWeight())
.max(Float::compareTo);
System.out.println(optionalApple);
Optional optionalApple = apples.stream()
.map(a->a.getWeight())
.min(Float::compareTo);
System.out.println(optionalApple);
apples.stream()
.map(Apple::getColor)
.map(String::toUpperCase)
.distinct()
.forEach(System.out::println);
目前我只知道调用sum求和
Optional optionalFloat = apples.stream()
.map(Apple::getWeight)
.distinct()
.reduce(Float::sum);
System.out.println(optionalFloat);
暂时先到这了,其他的看我后序学习情况吧。。