Lambda
定义
Lambda表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
理解:一些简单的接口 不用去写他的实现 通过lambde做一些简单的处理 lambde中的参数需要和对应接口中一致
public class LambdaTest {
public static void main(String[] args) {
LambdaTest lambdaTest = new LambdaTest();
/**
* 表达式使用{}必须要加return返回信息
*/
MathOperator addtion = (int a, int b) -> {
return a + b;
};
MathOperator subtraction = (int a, int b) -> a - b;
MathOperator division = (a, b) -> a / b;
System.out.println("10 + 5 = " + lambdaTest.operate(10, 5, addtion));
System.out.println("10 - 5 = " + lambdaTest.operate(10, 5, subtraction));
System.out.println("10 / 5 = " + lambdaTest.operate(10, 5, division));
SentMessage sentMessage = mes -> System.out.println("我是" + mes);
sentMessage.sayMessage("成龙");
}
interface MathOperator {
/**
* 用于计算两个数的操作
*
* @param a
* @param b
* @return
*/
int operation(int a, int b);
}
interface SentMessage {
/**
* 发送消息
*
* @param message
*/
void sayMessage(String message);
}
private int operate(int a, int b, MathOperator mathOperator) {
return mathOperator.operation(a, b);
}
}
变量作用域
lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,
int num = 1;
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
s.convert(2);
num = 5;
//报错信息:Local variable num defined in an enclosing scope must be final or effectively
final
Function
JDK8提供的多种内置的函数式接口
type | param |
---|---|
Consumer < T > | 接收T对象,不返回对象 |
Predicate < T > | 接收T对象,返回Boolean对象 |
Function < T,R > | 接收T对象,返回R对象 |
Supplier< T > | 不接收对象,返回T对象(例如工厂) |
UnaryOperator | 接收T对象,返回T对象 |
BinaryOperator | 接收两个T对象,返回T对象 |
在这些接口中有一些方法
Function<Integer, Integer> name = e -> e * 2;
Function<Integer, Integer> square = e -> e * e;
int value = name.andThen(square).apply(3);
System.out.println("andThen value=" + value);
int value2 = name.compose(square).apply(3);
System.out.println("compose value2=" + value2);
apply() 将Function对象应用到输入的参数上,然后返回计算结果。
andthen() 先执行当前函数的apply(),在执行内部的apply方法,例子结果为36
compose 先执行内部apply,在执行外部apply,例子结果18
示例
@Test
/**
* 没有输入参数,返回一个T类型的值
*/
public void supplierTest() {
Supplier<Integer> s = () -> {
return 1 + 1;
};
Integer integer = s.get();
log.info("结果" + integer);//结果2
}
/**
* 接收一个T类型的参数,并且没有返回值。
*/
@Test
public void consumerTest() {
Consumer<Integer> print = System.out::println;
Consumer<Integer> printPlusSelf = x -> System.out.println(x + x);
//注意:这里先输出10,在输出20
print.andThen(printPlusSelf).accept(10);
}
/**
* 接收T返回boolean
*/
@Test
public void predicateTest() {
Predicate<String> predicate = x -> {
return x.equals("predicate");
};
boolean test1 = predicate.test("666");
boolean test2 = predicate.test("predicate");
boolean test3 = predicate.or(m -> m.equals("666")).test("666");
boolean test4 = predicate.and(m -> m.equals("666")).test("666");
System.out.println(test1);//false
System.out.println(test2);//true
System.out.println(test3);//true
System.out.println(test4);//false
}
/**
* 接收T返回R
* andthen 先apply,再内部apply
* compose相反
*/
@Test
public void functionTest() {
Function<String, Integer> function = x -> x.equals("10") ? 0 : Integer.parseInt(x) + 1;
Integer apply = function.apply("10");
System.out.println(apply);//0
Integer apply1 = function.andThen(x -> x * x + 1).apply("5");//37
System.out.println(apply1);
Integer apply2 = function.compose(String::valueOf).apply("5");//6
System.out.println(apply2);
}
/**
* 接受两个T,返回一个T
*/
@Test
public void binaryOperatorTest(){
BinaryOperator<String> binaryOperator = (x,y) -> x+y;
String apply = binaryOperator.apply("我是", "大坏蛋");
System.out.println(apply);//我是大坏蛋
}
Stream
集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
理解: 就是操作数组或者集合 并对他们进行处理
例如 详情请查看链接
anyMatch()函数,用于检查列表中的任何元素是否满足给定条件。
forEach
Stream 提供了新的方法 ‘forEach’ 来迭代流中的每个数据。以下代码片段使用 forEach 输出了10个随机数:
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
flatMap()
将多个集合或者流合为一个集合
比如将list
示例代码
public class Test {
public static void main(String[] args) {
List<Integer> num = Arrays.asList(1, 2, 3, 4, 7, 6, 9, 8, 0, 99);
List<String> strings = Arrays.asList("qw", "er", "ty", "yu", "io", "pa");
//找出大于5的元素个数
long count = num.stream().filter(n -> n > 5).count();
System.out.println("大于5的个数"+count);
//为每个元素 平方 找出大于15的 并排序 再输出 前五个
num.stream().map(x->x*x).filter(x->x>15).sorted().limit(5).forEach(System.out::println);
//将不为空且不含e的元素 合并 单词之间用,隔开
String e = strings.stream().filter(string -> !string.isEmpty() && !string.contains("e")).collect(Collectors.joining(","));
System.out.println("将不为空且不含e的元素 合并 单词之间用,隔开为"+e);
}
}