写这篇笔记的起因
前几天由于业务需求,需要遍历对象列表并且根据某个属性排序,因为使用JDK工具可以简化代码及可维护性高,这里不再想for循环遍历了,于是想到了今天的主题,Lmabda。
那就开始Demo吧
创建一个对象:
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
这里咱们需要根据age排序:
public static void test1(){
List<Person> list = new ArrayList<>();
Random random = new Random();
for (int i = 0;i<10;i++ ) {
Person person = new Person();
person.setAge(random.nextInt(20));
person.setName("x"+i);
list.add(person);
}
//排序取值
List<Person> list1 = list.stream().sorted((u1, u2) -> u1.getAge().compareTo(u2.getAge()))
.collect(Collectors.toList());
System.out.println("排序之后的数据:" + list1);
}
借此机会也整理了一些Lmabda其他的操作,下边就直接上代码了:
public void test2(){
List<Person> list = new ArrayList<>();
for (int i = 0;i<10;i++ ) {
Person person = new Person();
person.setAge(i);
person.setName("x"+i);
list.add(person);
}
list.stream()
.filter(e -> e.getAge() > 5)
.limit(4) //获取前4条
.skip(4) //跳过前4条
// 需要流中的元素重写hashCode和equals方法
.distinct()
.forEach(person -> person.getAge());
List<Person> result2 = list.stream()
.filter(e -> e.getAge() > 5)
.collect(Collectors.toList());
result2.stream().forEach(person -> System.out.println(person.getAge()));
}
public static void test3(){
Map<String, String> map = new HashMap<>();
map.put("a","a1");
map.put("b","b1");
map.put("c","c1");
map.put("d","d1");
map.forEach((k, v) -> {
System.out.println("k=" + k + ",v=" + v);
});
}
public static void test4(){
List<String> list = new ArrayList<String>();
list.add("a");
list.add("bb");
list.add("ccc");
list.add("dddd");
System.out.println("list Lmabda遍历:");
list.forEach(v -> {
System.out.println(v);
});
System.out.println("list双冒号运算符遍历:");
list.forEach(System.out::println);
}
/**
* 注意:一个Stream流只可以使用一次,这段代码为了简洁而重复使用了数次,
* 因此会抛出 stream has already been operated upon or closed 异常。
*/
public static void test5(){
try {
Stream<String> stream2 = Stream.of("a", "b", "c");
// 转换成 Array
String[] strArray1 = stream2.toArray(String[]::new);
// 转换成 Collection
List<String> list1 = stream2.collect(Collectors.toList());
List<String> list2 = stream2.collect(Collectors.toCollection(ArrayList::new));//这里抛异常
Set set1 = stream2.collect(Collectors.toSet());
Stack stack1 = stream2.collect(Collectors.toCollection(Stack::new));
// 转换成 String 如果需要分割则Collectors.joining(",")
String str = stream2.collect(Collectors.joining()).toString();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void test6(){
List<String> list1 = Arrays.asList("a", "b", "c");
System.out.println("转换之前的数据:" + list1);
List<String> list2 = list1.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println("转换之后的数据:" + list2);
// 转换之后的数据:[A, B,C]
//类型转换
List<String> list3 = Arrays.asList("1", "2", "3");
System.out.println("转换之前的数据:" + list3);
List<Integer> list4 = list3.stream().map(Integer::valueOf).collect(Collectors.toList());
System.out.println("转换之后的数据:" + list4);
// [1, 2, 3]
//计算
List<Integer> list5 = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5 });
List<Integer> list6 = list5.stream().map(n -> n +1).collect(Collectors.toList());
System.out.println("数据:" + list6);
//数据:[2, 3, 4, 5, 6]
}
public static void test7(){
List<String> list = Arrays.asList("A", "B", "C", "D");
String result3 = list.stream().filter(str -> "A".equals(str)).findAny().orElse("none");
String result4 = list.stream().filter(str -> "E".equals(str)).findAny().orElse("none");
System.out.println("stream 过滤之后:" + result3);
System.out.println("stream 过滤之后:" + result4);
//stream 过滤之后:A
//stream 过滤之后:none
}
public static void test8(){
List<Person> list = new ArrayList<>();
for (int i = 0;i<10;i++ ) {
Person person = new Person();
person.setAge(i);
person.setName("x"+i);
list.add(person);
}
// 计算这个list中出现 姓名已"x"开头的,age 的和
int sum = list.stream().filter(person -> person.getName().startsWith("x")).mapToInt(person -> person.getAge()).sum();
System.out.println("计算结果:" + sum);
//计算结果:45
}
public static void test9(){
Random rd2 = new Random();
//升序排序
rd2.ints().limit(5).sorted().forEach(System.out::println);
}
/**
* parallelStream 是流并行处理程序的代替方法。
*/
public static void test10(){
List<String> strings = Arrays.asList("a", "b", "c", "c", "e","c", "s");
// 获取"c"的数量
long count = strings.parallelStream().filter(string -> string.equals("c")).count();
System.out.println("c个数:"+count);
//c个数:3
}
public static void test11(){
List<Person> list = new ArrayList<>();
for (int i = 0;i<10;i++ ) {
Person person = new Person();
person.setAge(i);
person.setName("x"+i);
list.add(person);
}
int max = list.stream().mapToInt(Person::getAge).max().getAsInt();
int min = list.stream().mapToInt(Person::getAge).min().getAsInt();
System.out.println("Person最大:" + max+",Person最小:"+min);
//Person最大:9,Person最小:0
}
/**
* allMatch:Stream 中全部元素符合则返回 true ;
* anyMatch:Stream 中只要有一个元素符合则返回 true;
* noneMatch:Stream 中没有一个元素符合则返回 true。
*/
public static void test12(){
List<Person> list = new ArrayList<>();
for (int i = 0;i<10;i++ ) {
Person person = new Person();
person.setAge(i);
person.setName("x"+i);
list.add(person);
}
boolean all = list.stream().allMatch(u -> u.getAge() > 5);
System.out.println("是否都大于5:" + all);
boolean any = list.stream().anyMatch(u -> u.getAge() > 5);
System.out.println("是否有一个大于5:" + any);
boolean none = list.stream().noneMatch(u -> u.getAge() > 5);
System.out.println("是否没有一个大于5的:" + none);
/**
* 是否都大于5:false
* 是否有一个大于5:true
* 是否没有一个大于5的:false
*/
}
public static void test13(){
String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
System.out.println("字符串拼接:" + concat);
List<Person> list = new ArrayList<>();
for (int i = 0;i<10;i++ ) {
Person person = new Person();
person.setAge(i);
person.setName("x"+i);
list.add(person);
}
Integer maxValue = list.stream().map((e)->e.getAge()).reduce(Integer::max).get();
System.out.println("最大年龄值:" + maxValue);
// 求和, 无起始值
int sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
System.out.println("有无起始值求和:" + sumValue);
// 求和, 有起始值
sumValue = Stream.of(1, 2, 3, 4).reduce(1, Integer::sum);
System.out.println("有起始值求和:" + sumValue);
// 有无起始值求和:10
// 有起始值求和:11
concat = Stream.of("a", "B", "c", "D", "e", "F").filter(x -> x.compareTo("Z") > 0).reduce("", String::concat);
System.out.println("过滤和字符串连接:" + concat);
//过滤和字符串连接:ace
}
/**
* 在 iterate 时候管道必须有 limit 这样的操作来限制 Stream 大小。
*/
public static void test14(){
System.out.println("从2开始生成一个等差数列:");
Stream.iterate(2, n -> n + 2).limit(5).forEach(x -> System.out.print(x + " "));
// 2 4 6 8 10
}
public static void test15(){
List<Person> list = new ArrayList<>();
for (int i = 0;i<10;i++ ) {
Person person = new Person();
person.setAge(i);
person.setName("x"+i);
list.add(person);
}
IntSummaryStatistics stats = list.stream().mapToInt((person) -> person.getAge()).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
}
public static void test16(){
List<SolveVo> list = new ArrayList<>();
for (int i = 0; i<10 ;i++) {
SolveVo solveVo = new SolveVo();
solveVo.setIsComment(i);
if(i > 6){
solveVo.setReplyId(1L);
}
list.add(solveVo);
}
list.stream().forEach(e->System.out.println("1:"+e.getIsComment()));
list.removeIf(e->e.getReplyId() == null);
list.stream().forEach(e->System.out.println("2:"+e.getIsComment()));
}
/**
* 移除元素
* 1:0
1:1
1:2
1:3
1:4
1:5
1:6
1:7
1:8
1:9
2:7
2:8
2:9
*/
题外:还有一个list根据某条件去重的例子( 去掉id相同的多余对象)
public static List<Map> getMap(List<Map> personList){
Set<Map> set = new TreeSet<Map>((map1, map2) -> ((Long)map1.get("id")).compareTo((Long)map2.get("id")));
set.addAll(personList);
return new ArrayList<>(set);
}
//多重过滤
List<Test> list = new ArrayList<>();
Test t = new Test();
t.setId(1L);
t.setName("");
list.add(t);
Test t1 = new Test();
t1.setId(1L);
t1.setName(null);
list.add(t1);
Test t2 = new Test();
t2.setId(1L);
t2.setName("xiaom");
list.add(t2);
Test t3 = new Test();
t3.setId(1L);
t3.setName("11314");
list.add(t3);
long count = list.stream().filter(e ->e.getName()!= null && !"".equals(e.getName())).count();
System.out.println(count);
// 2
List<Map<String,Object>> 多条件排序
List<Map<String,Object>> list= new ArrayList<>();
Map<String,Object> kpDetailMap = new HashMap<>(8);
kpDetailMap.put("wrongNums",1);
kpDetailMap.put("kpId",234);
list.add(kpDetailMap);
...
//按照知识点错题数降序排,错题数一样时按照知识点序号升序排
list.stream().sorted((e1,e2)->{
if(null == e1.get("wrongNums") || "" == e1.get("wrongNums")) {
e1.put("wrongNums", 0L);
}
if(null == e2.get("wrongNums") || "" == e2.get("wrongNums")) {
e2.put("wrongNums", 0L);
}
if(((Long)e1.get("wrongNums")).equals((Long)e2.get("wrongNums"))){
return Long .compare((Long)e1.get("kpId"),(Long) e2.get("kpId"));
}else {
return - Long .compare((Long)e1.get("wrongNums"),(Long) e2.get("wrongNums"));
}
}).collect(Collectors.toList())