本文已参与「新人创作礼」活动,一起开启掘金创作之路。
java Lambda表达式
Lambda表达式 以下简写为 L表达式
1. 什么是 @FunctionalInterface 函数式接口
1.1 只含有且只有 单个抽象方法 的 接口
1.2 必须是接口 不能是抽象类
1.3 接口中可以有default (默认) 方法,私有方法和其他的静态方法
1.4 主要用途 用作 Lambda 表达式的类型
2. Lambda表达式为什么和接口中的方法名称没有关系
2.1 首先来说 L表达式 作为函数参数 一定是有类型的,那他是什么类型呢??
String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));
x -> x.toUpperCase() 这个表达式是什么类型的呢?
2.2 常见通用单参数函数
第一种 有入有出 类似一种 函数隐射(或转化工厂) 把输入T 转化为输出V
对应于
也就是说在你写出 L表达式 t-> {...; return r;} 这儿L 表达式的类型就是 Function
在你想把输入a转化为输入b时 就用的是Function 类型的L表达式
第二种类型 只进不出 也叫消费型,就是把你传入的T 给消费掉了
L表达式 t->{ 没有返回值} ,注意返回类型是void 也就是没有返回值
第三种类型 只出不进 也叫生产者型
L 表达式 ()->{...; return t;} ,注意输入参数为void
第四种类型 这是一种Function 变体
就是输入一个表达式 返回bolean 类型的 (t)->{...; return true or false };
Predicate atLeast5 = x - > x > 5;
Predicate 类型是一种特殊的 Function: Function<T, Boolean>
Predicate类型一般用于 filter 过滤数据
第五种类型:没进没出型
2.3 常用双参数函数式接口
BinaryOperator extends BiFunction<T,T,T>
BinaryOperator 一般用于 L表达式型如: (Integer a,Float b)->{ return a+b; }
BinaryOperator<Long> addLongs = (x, y) - > x + y;
由于L 是实现的 函数式接口,而函数式接口中只有单个抽象方法,所有没有方法名称 也能从上下文推断出来。另外函数的调用只和传入和传出的参数有关。
filter():对元素进行过滤; Predicate sorted():对元素排序; function map():元素的映射;function distinct():去除重复元素;
3. lambada 表达式和 实现接口的关系
比如 线程的Runnable 接口
一般的代码:
Runnable task=new Runnable() {
@Override
public void run() {
System.out.println("努力工作中...");
}
};
或
Runnable task=()->{ System.out.println("努力工作中..."); }
Thead t=new Thead(task);
t.start();
也就是说
()->{ System.out.println("努力工作中..."); } 是 Runnable 类型的实例
4. lambda 表达式的一般写法
5. 集合类的流式编程 【数据处理的工序】
先看一下整体 www.ibm.com/developerwo…
5.1 理解Map方法
以下代码把Integer List 隐射为String List
List<Integer> numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4,3);
List<String> distinct = numbers.stream().map( i -> i+"" ).distinct().collect(Collectors.toList());
map 中的 i->i+"" 表达式就是 Function 类型的
再看一个例子
List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.","Canada");
String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));
5.2 理解 filter
List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList());
x -> x.length()> 2 是Predicate 的类型
其他的可以参考这里 http://www.importnew.com/16436.html
5.3 理解 分组 groupby 和收集器 collectors
例1:把课程信息组装成map
List<BwXyCourseinfo> courseList = courseinfoService.queryAll(pMap);
Map<String, BwXyCourseinfo> courseMap = courseList.stream().collect(
Collectors.toMap(
(BwXyCourseinfo o) -> o.getId(),
(BwXyCourseinfo o) -> o,
(k1, k2) -> {
throw new RuntimeException(String.format("Duplicate key for values %s and %s", k1,k2));
}, LinkedHashMap::new));
例2:
// 提取班号并去重复
Set<String> bjmcSet = list.stream().map(o -> o.getClassid()).collect(Collectors.toSet());
List<String> bjmcs = new ArrayList<String>(bjmcSet);
Map<String, Object> params = new HashMap<String, Object>();
params.put("bjmcs", bjmcs);
final Map<String, BwXyBjbm> bjMap = bjbmService.getBwXyBjbmMap(params);
// 填充学院id
list.stream().filter(o -> null != o.getClassid()).forEach(o -> {
BwXyBjbm bj = bjMap.get(o.getClassid());
if (null != bj) {
o.setCollegeid(bj.getSsxy());
}
});
例3: 字符串拼接
List names=new ArrayList<String>();
names.add("1");
names.add("2");
names.add("3");
System.out.println(String.join("-", names));
输出:
1-2-3
带前后缀
StringJoiner sj = new StringJoiner(",", "[", "]");
sj.add("a").add("b").add("c");
System.out.println("The final Joined string is " + sjr);
输出: "[a,b,c]
// 中间以or 连接,开始 and ( 结尾 )
category = new StringJoiner(" or ", " and ( ", " ) ");
例3:分组 ,这个比较费脑
List<ExamQuestionMain> mList = mainDao.queryAll(pMap);
// 按科目分组,英语,语文,数学,专业知识
Map<String, List<ExamQuestionMain>> subjectQuetionMap = mList.stream()
.collect(
Collectors.groupingBy(
(ExamQuestionMain o) -> o.getSubject(),
Collectors.toList()));
下边这个例子更费脑
// 按问题id 分组 获取属性的 id列表
List<ExamQuestionAttribute> categoryList =null;
Map<String, List<String>> categoryMap = categoryList.stream().collect
(
Collectors.groupingBy(
ExamQuestionAttribute::getQuestionId,
Collectors.mapping(ExamQuestionAttribute::getAttributeId, Collectors.toList())
)
);
// 一个 Question问题有多个Attribute
//在groupingBy 操作时 返回的类型为 Map<String, List<ExamQuestionAttribute>>
即 {
key = QuestionId这个试题的id
value= 这个试题对应的所有Attribute对象
}
//但是 我想要 {key =QuestionId这个试题的id , value=这个试题对应的所有 Attribute对象的id}
即返回结果 不是 Map<String, List<ExamQuestionAttribute>> 而是Map<String, List<String>>
所以还需要再次map一下也就是把 ExamQuestionAttribute 对象转化为一个String对象
Collectors.mapping(ExamQuestionAttribute::getAttributeId, Collectors.toList()
分组计数