在最近的工作中遇到一种情况,需要将多条记录按ID分类,并且进行判断。然后我发现如果在数据从数据库提取这个过程中进行条件过滤的话,会不可避免的导致循环中多次访问数据库。目前因数据的量不是很大,还能接受,但一旦数据量过大,这个方法将导致处理效率极低。为了找到解决方案,我查询到了java8的特性——steam.
概念:Steam 是Java8 提出的一个新概念,不是输入输出的 Stream 流,而是一种用函数式编程方式在集合类上进行复杂操作的工具。简而言之,是以内部迭代的方式处理集合数据的操作,内部迭代可以将更多的控制权交给集合类。Stream 和 Iterator 的功能类似,只是 Iterator 是以外部迭代的形式处理集合数据的操作。
目前需要达到的效果。
1,将多条具有相同ID的记录分组并保存
2,迭代每一组,并对其中一个元素进行判断
3,获取判断结果,并针对该结果进行一个操作。
大致代码如下:
1
// test为自定义的测试方法,getcode是其中用来获取code的方法,将根据code自动分类
//分类后将以 Map 形式返回
Map<Integer,List<test>> groupbycode = testlist.stream().collect(Collectors.groupingBy(test::getcode));
2
对Map进行迭代,Map提供一个内部接口Entry,Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry<K,V>。它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法。
for(Map.Entry<Integer,List<test>> entry : groupbycode.entrySet()) {
//循环获取每一个以code分类的组,并获取对应的key值和value值。
Integer mapKey = entry.getKey(); //获取key
List<test> mapValue = entry.getValue(); //获取value
}
这个时候我将value打印出来时,发现里面居然是(包名.test@27d6c5e0)这样的东西,不是我想象的直接呈现内容,因此我查询了一下,entry.getValue获得的是什么东西。
然鹅我并没查到...我只能知道这个指向对应的类,这个是否就是指向该类的地址?
在论坛发帖得到回复:“类名加类的hashcode值,不是真实内存地址,不过可以当地址来理解”
感觉大致明白是怎么回事了。
3
在 List<test> mapValue = entry.getValue(); //这里获取的是每一个集合
通过对mapValue再次遍历,能够获得里面每一个类,且能够对该类进行操作。
这里我尝试使用steam 的 filter来过滤出我要的属性
//过滤出集合中status为“in”的类,并将这些类集合到 list pdIN 中。
List<test> pdIN = mapValue.stream().filter(x ->x.getStatus().equals("in")).collect(Collectors.toList());
解释:x ->x.getStatus().equals("in")
为过滤器条件,意思为遍历 mapValue中类的属性status是否等于"in",如果是则通过过滤器。
解释:.collect(Collectors.toList());
steam()流最后都需要一个结束操作(过滤器为中间操作),该操作的作用是将steam流中的数据提取成一个List并返回。