JDK8的集合STREAM
JDK8的Stream
JAVA开发小伙伴们应该使用JDK8好多年了,
但是STREAM有很多小伙伴想用确用不好,用起来还感觉有点迷糊。
网上也有很多人在写,都是在自定义一些实体类操作一些SET或者GET方法,我今天给你们讲一个拿过去就可以运行的测试方法。
不抠细节拿过去就可以尝试
重要的话说三遍:一定要多尝试、一定要多尝试、一定要多尝试
背景 想暴富
作为一个新时代的码农,农民工想一夜暴富了我要买个彩票,
所以我去网站上把100期的双色球的一些数据拿过来,
看一看最近出现次数最多的号码,最近平均遗漏最少的球号码;
从中选择一组自己喜欢的球号周末去买一张彩票。
开始操练代码
授人以鱼不如授人以渔
引入的依赖 谷歌的这个操作集合类的工具包 ,同学们可以去尝试用一下
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.junit.Test;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.function.Function;
import java.util.stream.Collectors;
@Test
public void testDoubleBall() {
//100期内 双色球出现数据统计情况
//出现次数
String cxcs = "15,15,15,18,19,19,25,9,17,25,20,19,14,26,27,13,18,14,26,23,14,15,16,26,14,19,20,23,14,15,19,18,10";
List<String> cxcsList = Splitter.on(",").splitToList(cxcs);
//平均遗漏次数
String pjylcs = "6,6,6,5,5,5,4,11,5,4,5,5,7,3,3,7,5,7,3,4,7,6,6,3,7,5,5,4,7,6,5,5,10";
List<String> pjylcsList = Splitter.on(",").splitToList(pjylcs);
//最大遗漏次数
String zdylcs = "14,20,18,13,11,20,12,30,16,15,20,13,22,13,9,29,17,17,18,15,27,21,17,9,21,20,16,10,18,24,16,15,21";
List<String> zdylcsList = Splitter.on(",").splitToList(zdylcs);
//最大连出次数
String zdlccs = "3,2,1,2,2,2,4,2,2,3,4,3,2,3,2,2,2,2,4,4,4,2,2,4,1,3,3,3,2,2,3,2,2";
List<String> zdlccsList = Splitter.on(",").splitToList(zdlccs);
List<Map<String, Object>> list = Lists.newArrayList();
for (int i = 0; i < 33; i++) {
Map<String, Object> ball = Maps.newHashMap();
ball.put("qh", i + 1);
ball.put("cxcs", cxcsList.get(i));
ball.put("pjylcs", pjylcsList.get(i));
ball.put("zdylcs", zdylcsList.get(i));
ball.put("zdlccs", zdlccsList.get(i));
list.add(ball);
}
//写法一 函数比较
//讲一下这个函数 FUNCTION<T,R>;mk就是入参MAP对象,返回Interger对象,常见的业务中会用String类型存储数字,所以我用JSON对象转一下,习惯。
Function<Map<String, Object>, Integer> cxcsFun = mk -> {
return new JSONObject(mk).getInteger("cxcs");
};
Function<Map<String, Object>, Integer> zdylcsFun = mk -> {
return new JSONObject(mk).getInteger("zdylcs");
};
//这里定义的函数可以灵活使用下面你就看见了
Function<Map<String, Object>, Integer> pjylcsFun = mk -> {
return new JSONObject(mk).getInteger("pjylcs");
};
Function<Map<String, Object>, Integer> zdlccsFun = mk -> {
return new JSONObject(mk).getInteger("zdlccs");
};
//写法二 自定义比较
Comparator<Map<String, Object>> comparator = (a, b) -> {
JSONObject aJson = new JSONObject(a);
JSONObject bJson = new JSONObject(b);
int com1 = aJson.getInteger("cxcs");
int com2 = bJson.getInteger("cxcs");
//这里判断com1 > com2 或者 com1 < com2||reversed()方法进行控制改变是否降序升序
if (com1 > com2) {
return 1;
} else if (com1 == com2) {
return 0;
} else {
return -1;
}
};
System.out.println("写法1输出结果");
list.stream().sorted(comparator.reversed()).limit(6).forEach(ball -> {
System.out.println(ball.toString());
});
System.out.println("-----------------分割线-----------------");
System.out.println("写法2输出结果");
//comparing 默认是升序排列
list.stream().sorted(Comparator.comparing(cxcsFun).reversed().thenComparing(pjylcsFun))
.limit(10)
.forEach(ball -> {
System.out.println(ball.toString());
});
System.out.println("-----------------分割线-----------------");
System.out.println("写法3输出结果");
list.stream().sorted(Comparator.comparing(cxcsFun).reversed())
.sorted(Comparator.comparing(pjylcsFun))
.limit(10).forEach(ball -> {
System.out.println(ball.toString());
});
System.out.println("-----------------分割线-----------------");
System.out.println("-----------------分组函数使用也是比较常用的-----------------");
Map<Integer, List<Map<String, Object>>> gbMap = list.stream().sorted(Comparator.comparing(cxcsFun).reversed())
.limit(10)
.collect(Collectors.groupingBy(pjylcsFun));
gbMap.forEach((k, m) -> {
System.out.println(k);
m.stream().forEach(ball -> System.out.println(ball.toString()));
});
}
操练结局
写法1输出结果
{pjylcs=3, zdlccs=2, zdylcs=9, qh=15, cxcs=27}
{pjylcs=3, zdlccs=3, zdylcs=13, qh=14, cxcs=26}
{pjylcs=3, zdlccs=4, zdylcs=18, qh=19, cxcs=26}
{pjylcs=3, zdlccs=4, zdylcs=9, qh=24, cxcs=26}
{pjylcs=4, zdlccs=4, zdylcs=12, qh=7, cxcs=25}
{pjylcs=4, zdlccs=3, zdylcs=15, qh=10, cxcs=25}
-----------------分割线-----------------
写法2输出结果
{pjylcs=3, zdlccs=2, zdylcs=9, qh=15, cxcs=27}
{pjylcs=3, zdlccs=3, zdylcs=13, qh=14, cxcs=26}
{pjylcs=3, zdlccs=4, zdylcs=18, qh=19, cxcs=26}
{pjylcs=3, zdlccs=4, zdylcs=9, qh=24, cxcs=26}
{pjylcs=4, zdlccs=4, zdylcs=12, qh=7, cxcs=25}
{pjylcs=4, zdlccs=3, zdylcs=15, qh=10, cxcs=25}
{pjylcs=4, zdlccs=4, zdylcs=15, qh=20, cxcs=23}
{pjylcs=4, zdlccs=3, zdylcs=10, qh=28, cxcs=23}
{pjylcs=5, zdlccs=4, zdylcs=20, qh=11, cxcs=20}
{pjylcs=5, zdlccs=3, zdylcs=16, qh=27, cxcs=20}
-----------------分割线-----------------
写法3输出结果
{pjylcs=3, zdlccs=2, zdylcs=9, qh=15, cxcs=27}
{pjylcs=3, zdlccs=3, zdylcs=13, qh=14, cxcs=26}
{pjylcs=3, zdlccs=4, zdylcs=18, qh=19, cxcs=26}
{pjylcs=3, zdlccs=4, zdylcs=9, qh=24, cxcs=26}
{pjylcs=4, zdlccs=4, zdylcs=12, qh=7, cxcs=25}
{pjylcs=4, zdlccs=3, zdylcs=15, qh=10, cxcs=25}
{pjylcs=4, zdlccs=4, zdylcs=15, qh=20, cxcs=23}
{pjylcs=4, zdlccs=3, zdylcs=10, qh=28, cxcs=23}
{pjylcs=5, zdlccs=4, zdylcs=20, qh=11, cxcs=20}
{pjylcs=5, zdlccs=3, zdylcs=16, qh=27, cxcs=20}
-----------------分割线-----------------
-----------------分组函数使用也是比较常用的-----------------
3
{pjylcs=3, zdlccs=2, zdylcs=9, qh=15, cxcs=27}
{pjylcs=3, zdlccs=3, zdylcs=13, qh=14, cxcs=26}
{pjylcs=3, zdlccs=4, zdylcs=18, qh=19, cxcs=26}
{pjylcs=3, zdlccs=4, zdylcs=9, qh=24, cxcs=26}
4
{pjylcs=4, zdlccs=4, zdylcs=12, qh=7, cxcs=25}
{pjylcs=4, zdlccs=3, zdylcs=15, qh=10, cxcs=25}
{pjylcs=4, zdlccs=4, zdylcs=15, qh=20, cxcs=23}
{pjylcs=4, zdlccs=3, zdylcs=10, qh=28, cxcs=23}
5
{pjylcs=5, zdlccs=4, zdylcs=20, qh=11, cxcs=20}
{pjylcs=5, zdlccs=3, zdylcs=16, qh=27, cxcs=20}
总结使用技巧
1、自定义的FUNCTION函数可以任意使用的stream的需要函数的参数方法中,
你无论是排序操作还是,分组操作都可以一个函数多次使用
2、STREAM后面可以跟很多操作,排序,分组,归集,遍历
这里面有中间操作例如排序,过滤,也有最终操作如遍历,归集等。
中间操作就是可以在写遍历操作或者其他最终操作,
但是终端操作就是结束了