Java8新特性

推荐几篇写的很好的文章:

Java 8简明教程

Java8 函数式编程探秘

Java8学习笔记

Java 8开发的4大顶级技巧

Java8新特性教程

下面是我参考整理的一些代码,记录一下用法,备忘

 

Java8新特性-- Collectores

一、归约和汇总

1. 查找最大最小值

maxBy(Comparator)
minBy(Comparator)

2. 汇总

求和:
summingInt(XX::getX)
summingLong(XX::getX)
summingDouble(XX::getX)
求平均值:
averagingInt(XX::getX)
averagingDouble(XX::getX)
averagingLong(XX::getX)
综合方法,和,平均,最大最小全求出来:
summarizingInt(XX:getX)
summarizingDouble(XX:getX)
summarizingLong(XX:getX)

3. 连接字符串

joining()  --内部使用StringBuffer拼接
joining(", ")  --可以添加参数,用什么隔开

4. 广义的归约汇总

reducing(M,N,W) 需要3个参数 

M   ->  初始值
N   ->  XX::getX
W   ->  一个lamda转换函数

reducing(W) 可以一个参数

W   ->  一个Lambda转换函数

二、分组

Collectors.groupingBy()

1.简单分组

Collectors.groupingBy(W)  W为一个Lambda
public enum Level { LOW, NORMAL, HIGH };
Map> maps = trans.parallelStream().collect(groupingBy(Transaction::getValue));

//返回的是Key
Map> maps2 = trans.parallelStream().collect(groupingBy(t -> {
    if (t.getValue() <= 500)
        return Level.LOW;
    else if (t.getValue() <= 1000)
        return Level.NORMAL;
    else
        return Level.HIGH;
}));

2.多级分组

多级就是类似按照这一级规则分完组,继续按照下个规则继续分组,将内存传递给外层

即为groupingBy套用groupingBy
Collectors.groupingBy(W, groupingBy(M))  W为一个分类函数 M可以为任何类型
Map>> maps3 = trans.parallelStream()
    .collect(groupingBy(Transaction::getYear, groupingBy(t -> {
        if (t.getValue() <= 500)
            return Level.LOW;
        else if (t.getValue() <= 1000)
            return Level.NORMAL;
        else
            return Level.HIGH;
    })));
 

3.按子组收集数据

传递给groupingBy的第二个收集器可以是==任何类型==

普通的单函数groupingBy(f) 实际上为 groupingBy(f, toList())

3.1 把收集器结果转换为另一种类型

Collectors.collectingAndThen(W,M) 返回一个收集器
W:要转换的收集器 M:转换函数
Map maps5 = trans.stream().collect(groupingBy(Transaction::getYear,
    collectingAndThen(maxBy(comparing(Transaction::getValue)), Optional::get)));

3.2 于groupingBy联合使用的其他收集器

Collectors.mapping(W,M) 返回一个收集器
W:转换函数 M:收集函数
这里是先将值映射为Level,将生成的Level流传给toSet,然后返回:

Map> maps7 = trans.stream()
    .collect(groupingBy(Transaction::getYear, Collectors.mapping(t -> {
        if (t.getValue() <= 500)
            return Level.LOW;
        else if (t.getValue() <= 1000)
            return Level.NORMAL;
        else
            return Level.HIGH;
    }, toSet())));
    
Map> maps7 = trans.stream()
    .collect(groupingBy(Transaction::getYear, Collectors.mapping(t -> {
        if (t.getValue() <= 500)
            return Level.LOW;
        else if (t.getValue() <= 1000)
            return Level.NORMAL;
        else
            return Level.HIGH;
    }, Collectors.toCollection(HashSet::new))));
    
Collectors.toCollection(HashSet::new) 可以控制其生成的流的类型

三、分区

1. 分区

Collectors.partitioningBy(W)  W必须为返回boolean值的函数
Collectors.partitioningBy(W,M)  W必须为返回boolean值的函数 M为收集器
直接按照某boolean值分区 true|false
Map> map1 = trans.stream().collect(Collectors.partitioningBy(Transaction::getIsOk));

可以添加收集器参数
Map>> map2 = trans.stream()
    .collect(Collectors.partitioningBy(Transaction::getIsOk, groupingBy(Transaction::getYear)));

可以使用collectingAndThen来完成连续收集功能
Map map3 = trans.stream().collect(Collectors.partitioningBy(Transaction::getIsOk,
    collectingAndThen(maxBy(Comparator.comparing(Transaction::getValue)), Optional::get)));

2.按照质数非质数分区

private boolean isPrime(int num) {
    int num2 = (int) Math.sqrt((double) num);
    return IntStream.rangeClosed(2, num2).noneMatch(t -> num % t == 0);
}

private  Map> getNum(int n) {
    return IntStream.rangeClosed(2, n).boxed().collect(Collectors.partitioningBy(t -> isPrime(t)));
}

Map> map4 = getNum(N);

 

import com.alibaba.fastjson.JSON;
 
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
public class Main {
    
    public static void main(String[] args) {
 
        // 将Stream转换成List或Set
        Stream stream = Stream.of("I", "love", "you", "you", "too");
        List stringList = stream.collect(Collectors.toList()); // (1)
        System.out.println(JSON.toJSONString(stringList));//["I","love","you","you","too"]
 
//        Set set = stream.collect(Collectors.toSet()); // (2)
//        System.out.println(JSON.toJSONString(set));//["love","too","I","you"]
 
        //返回的是一个String,不是List
        String string1 = stringList.stream().collect(Collectors.joining());
        System.out.println(string1);//Iloveyouyoutoo
 
 
        String string2 = stringList.stream().collect(Collectors.joining(","));
        System.out.println(string2);//I,love,you,you,too
 
//        public static Collector joining(CharSequence delimiter,
//                CharSequence prefix,
//                CharSequence suffix) {
        String string3 = stringList.stream().collect(Collectors.joining(",", "{", "}"));
        System.out.println(string3);//{I,love,you,you,too}
 
        List list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("C");
        Set stringSet = list.stream().collect(Collectors.toSet());
        System.out.println(JSON.toJSONString(stringSet));//["A","B","C"]
 
        //------------------------------------------------------------------------
        Subject subject1 = new Subject(1, "语文", 91.0);
        Subject subject2 = new Subject(2, "数学", 94.0);
        Subject subject3 = new Subject(3, "英语", 92.0);
        Subject subject4 = new Subject(4, "语文", 90.0);
        List subjectList = new ArrayList<>();
        subjectList.add(subject1);
        subjectList.add(subject2);
        subjectList.add(subject3);
        subjectList.add(subject4);
 
        Map map1 = subjectList.stream().collect(Collectors.toMap(Subject::getId, Subject::getName));
        System.out.println(JSON.toJSONString(map1));//{1:"语文",2:"数学",3:"英语",4:"语文"}
 
//        Map map2 = subjectList.stream().collect(Collectors.toMap(Subject::getName, Subject::getGrade));
//        出现重复key,报错:java.lang.IllegalStateException: Duplicate key 91.0
//        System.out.println(JSON.toJSONString(map2));
 
        Map map2 = subjectList.stream().collect(Collectors.toMap(Subject::getName, Subject::getGrade,
                (oldValue, newValue) -> newValue));//方法引用只带方法名即可,不必带圆括号
        //出现重复key则用新值覆盖
        System.out.println(JSON.toJSONString(map2));//{"数学":94.0,"语文":90.0,"英语":92.0}
 
        Map map3 = subjectList.stream().collect(Collectors.toMap(Subject::getName, Subject::getGrade,
                (oldValue, newValue) -> oldValue));
        //出现重复key继续用旧值
        System.out.println(JSON.toJSONString(map3));//{"数学":94.0,"语文":91.0,"英语":92.0}
 
        Map map4 = subjectList.stream().collect(Collectors.toMap(Subject::getId,
                Function.identity(), (oldValue, newValue) -> newValue));
        System.out.println(JSON.toJSONString(map4));
        //{1:{"grade":91.0,"id":1,"name":"语文"},2:{"grade":94.0,"id":2,"name":"数学"},3:{"grade":92.0,"id":3,"name":"英语"},4:{"grade":90.0,"id":4,"name":"语文"}}
 
        //value是对象
        Map map5 = subjectList.stream().collect(Collectors.toMap(Subject::getName,
                Function.identity(), (oldValue, newValue) -> oldValue, HashMap::new));
        System.out.println(JSON.toJSONString(map5));
        //{"数学":{"grade":94.0,"id":2,"name":"数学"},"语文":{"grade":91.0,"id":1,"name":"语文"},"英语":{"grade":92.0,"id":3,"name":"英语"}}
 
        //这里的key必须是boolean型
        //按照某个条件是否成立分为两组,value是list
        Map> stringListMap1 = subjectList.stream().collect(Collectors.partitioningBy(s -> s.getName().equals("语文")));
        System.out.println(JSON.toJSONString(stringListMap1));
        //{false:[{"grade":94.0,"id":2,"name":"数学"},{"grade":92.0,"id":3,"name":"英语"}],true:[{"grade":91.0,"id":1,"name":"语文"},{"grade":90.0,"id":4,"name":"语文"}]}
 
        //按照某个条件分为多组,value是list
        Map> stringListMap2 = subjectList.stream().collect(Collectors.groupingBy(Subject::getName));//这里只能是Subject::getName,如果写成subject.getName()则报错
        System.out.println(JSON.toJSONString(stringListMap2));
        //{"数学":[{"grade":94.0,"id":2,"name":"数学"}],"语文":[{"grade":91.0,"id":1,"name":"语文"},{"grade":90.0,"id":4,"name":"语文"}],"英语":[{"grade":92.0,"id":3,"name":"英语"}]}
 
        //使用parallelStream是多管道处理,效率比stream高很多
        Map> stringListMap5 = subjectList.parallelStream().collect(Collectors.groupingBy(Subject::getName));//这里只能是Subject::getName,如果写成subject.getName()则报错
        System.out.println(JSON.toJSONString(stringListMap5));
        //{"数学":[{"grade":94.0,"id":2,"name":"数学"}],"语文":[{"grade":91.0,"id":1,"name":"语文"},{"grade":90.0,"id":4,"name":"语文"}],"英语":[{"grade":92.0,"id":3,"name":"英语"}]}
 
        //按某个条件统计,每种key存在多少个总数
        Map stringListMap3 = subjectList.stream().collect(Collectors.groupingBy(Subject::getName, Collectors.counting()));
        System.out.println(JSON.toJSONString(stringListMap3));
        //{"数学":1,"语文":2,"英语":1}
 
        //按某个条件统计,key的某个属性的列表
        Map> stringListMap4 = subjectList.stream().collect(Collectors.groupingBy(Subject::getName,
                Collectors.mapping(Subject::getGrade, Collectors.toList())));
        System.out.println(JSON.toJSONString(stringListMap4));
        //{"数学":[94.0],"语文":[91.0,90.0],"英语":[92.0]}
 
        //------------------------------------------------------------------------
        List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
 
        //串行输出
        numbers.stream().forEach(System.out::print);//123456789
 
        System.out.println();
 
        //并行输出
        numbers.parallelStream().forEach(System.out::print);//658973421
 
        System.out.println();
 
        //并行有序输出
        numbers.parallelStream().forEachOrdered(System.out::print);//123456789
    }
}
package com.lgx.jdk8.part02;
 
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * Collectors其它一些方法的使用
 */
public class Test11Collectors {
    public static void main(String[] args) {
        User user1 = new User("zhangsan", 60, 20);
        User user2 = new User("lisi", 80, 23);
        User user3 = new User("zhangsan", 80, 24);
        User user4 = new User("wangwu", 50, 24);
        User user5 = new User("wangwu2", 50, 24);
 
        List userList = Arrays.asList(user1, user2, user3, user4, user5);
 
        //算出分数最小的那个并输出
        userList.stream().collect(Collectors.minBy(Comparator.comparingInt(User::getScore))).ifPresent(System.out::println);
 
        //算出分数最大的那个并输出(无法做到多个并列的时候求值)
        Optional optional = userList.stream().collect(Collectors.maxBy(Comparator.comparingInt(User::getScore)));
        //optional.isPresent(System.out::println);//isPresent是判断是否存在,不能接受参数
        optional.ifPresent(System.out::println);//直接使用时ifPresent
 
        //算出分数平均值并输出
        double averagint = userList.stream().collect(Collectors.averagingInt(User::getScore));
        System.out.println("averagint = " + averagint);
 
        //算出分数总和并输出
        int summingInt = userList.stream().collect(Collectors.summingInt(User::getScore));
        System.out.println("summingInt = " + summingInt);
 
        //算出汇总信息
        IntSummaryStatistics intSummaryStatistics = userList.stream().collect(Collectors.summarizingInt(User::getScore));
        System.out.println("intSummaryStatistics = " + intSummaryStatistics);
 
        //拼接名字
        String nameStrs = userList.stream().map(User::getName).collect(Collectors.joining(", "));
        System.out.println("nameStrs = " + nameStrs);
 
        //拼接名字,调用另外一个方法,可以加前缀和后缀
        String nameStrs2 = userList.stream().map(User::getName).collect(Collectors.joining(", ", "[", "]"));
        System.out.println("nameStrs2 = " + nameStrs2);
 
        //分组:按照分数(返回的map的key是根据分组的条件来决定的,score是int,那么key就是Integer)
        Map> scoreUsers = userList.stream().collect(Collectors.groupingBy(User::getScore));
        System.out.println("scoreUsers = " + scoreUsers);
 
        //二级分组:线按照分数分组,返回一个Map>, 在根据用户名分组
        Map>> scoreNameUsers = userList.stream().collect(Collectors.groupingBy(User::getScore, Collectors.groupingBy(User::getName)));
        System.out.println("scoreNameUsers = " + scoreNameUsers);
 
        //分区,是否及格
        Map> jigeUsers = userList.stream().collect(Collectors.partitioningBy(user -> user.getScore() >= 60));
        System.out.println("jigeUsers = " + jigeUsers);
 
        //二级分区,是否及格,及格里面是否大于80
        Map>> youxiuUsers = userList.stream().collect(Collectors.partitioningBy(user -> user.getScore() >= 60, Collectors.partitioningBy(user -> user.getScore() >= 80)));
        System.out.println("youxiuUsers = " + youxiuUsers);
 
        //分区,是否及格,算出及格的个数
        Map jigeUserCount = userList.stream().collect(Collectors.partitioningBy(user -> user.getScore() >= 60, Collectors.counting()));
        System.out.println("jigeUserCount = " + jigeUserCount);
 
        //先按照名字分组,获取每个分组分数最小的
        Map UserCount = userList.stream().collect(Collectors.groupingBy(User::getName, Collectors.collectingAndThen(Collectors.minBy(Comparator.comparingInt(User::getScore)), Optional::get)));
        System.out.println("UserCount = " + UserCount);
 
 
    }
}

 

Java8新特性——Map的新方法

import java.util.HashMap;
import java.util.Map;
 
import org.junit.Test;
 
/**
 * Map
 */
public class NewMap {
 
	@Test
	public void testMap(){
		
		Map map = new HashMap<>();
		for(int i=0; i<10; i++){
			//putIfAbsent使得我们不用写是否为null值的检测语句;
			map.putIfAbsent(i, "val_"+i);
		}
		
		//-------1------maps不支持流。然而现在maps包括了许多新的非常有用的方法用于执行通用任务:		
		//forEach使用consumer来对map中的每个元素进行操作,执行通用任务。
		map.forEach( (key,value) -> System.err.println(key +" : "+value) );
		
		//----------2-------------------使用功能性函数在map里执行代码:		
		//将key为3对应的值(val_3)改为  "val_3"+3*10 = val_330
		map.computeIfPresent(3, (num, val) -> val + num*10);  
		System.err.println(map.get(3)); //val_330
		  
		//将key为9对应的值(val_9)改为  null
		map.computeIfPresent(9, (num, val) -> null);  
		map.containsKey(9);     // false  
		  
		//将key为23对应的值(null)改为  "val_23"
		map.computeIfAbsent(23, num -> "val" + num);  
		map.containsKey(23);    // true  
		
		map.put(3, null);
		//如果key为3对应的值改为null, 将其值改为"bam"
		map.computeIfAbsent(3, num -> "bam");  
		System.err.println(map.get(3));// bam  
		
		//---------3--------------删除给定键所对应的元素。删除操作还需要满足给定的值需要和map中的值相等:
		map.remove(3, "val3");  
		map.get(3);             // val33  
		  
		map.remove(3, "val33");  
		map.get(3);             // null  	 
		
		
		//----------4--------其他一些帮助性方法:
		map.getOrDefault(44, "404 not found");
		
		//---------------5----------------合并map中的实体
		//此时map.get(9)=null
		map.merge(9, "val999", (value, newValue) -> value.concat(newValue));  
		map.get(9);             // val999
		System.err.println(map.get(9));
		  
		map.merge(9, "concat", (value, newValue) -> value.concat(newValue));  
		map.get(9);             // val999concat  
		System.err.println(map.get(9));
		 	
	}
}

 

你可能感兴趣的:(Java8新特性)