简述
文章主要通过几个假设的场景,阐述如何使用java8的stream工具包处理数据。代码已托管于github和gitee上,引用读者请注明出处。
场景一:
例如有如下数据
/*
* 使用stream类创建集合
*/
private static List<User> userList = Stream.of(new User("1","Sherwin","10.13.113.0"),
new User("2","Allen","10.13.110.1"),
new User("3","Sky","10.12.113.3"),
new User("4","Tracy","10.13.113.1"),
new User("5","Alice","10.13.103.204"),
new User("6","William","10.13.112.10")).collect(Collectors.toList());
目前需要过滤出ipAddress以某种条件开头的数据,然后转为map存储,供调用者使用,代码对比for和if-else组合精简得不是一点半点,如下
/* @description: 过滤出集合中想要的数据,例如过滤出ipAddress以condition开头的数据,然后转为map存储
* @author: Sherwin Liang
* @timestamp: 2021/11/5 23:10
* @param: condition 过滤条件
* @return: Map<String, User> 过滤后的user Map
*/
public static Map<String, User> filterUser(final String condition){
return userList.stream().filter(u->u.getIpAddress().startsWith(condition))
.collect(Collectors.toMap(User::getIpAddress,u->u));
}
场景二:
需要查询某个字符在文件中出现的次数,我们可以使用stream流逐行统计,而不用直接使用IO流读取文件,献上代码,需要注意Steam里得形参都是默认指定为final的。
/* @description: 查询文件中某个字符出现的次数
* @author: Sherwin Liang
* @timestamp: 2021/11/6 11:46
* @param: filePath 文件路径
* @param: character 查找的字符
* @return: long 出现次数
*/
public static long countCharacterInFile(final String filePath, final Character character){
final AtomicInteger atomicInteger = new AtomicInteger();
try(Stream<String> lines = Files.lines(Paths.get(filePath))){
lines.map(l->l.toCharArray()).forEach(chars -> {
for(char c:chars){
if(c==character)
atomicInteger.getAndIncrement();
}
});
}catch(IOException e){
e.printStackTrace();
atomicInteger.set(0);
}
return atomicInteger.intValue();
}
场景三:
还是场景一中的数据,我们来对其按一定的规则来排序,例如按用户名字的长度
/* @description: 排序
* @author: Sherwin Liang
* @timestamp: 2021/11/6 12:09
* @param: originalList 原列表
* @param: comparator 比较器
* @return: List<User> 排序后的列表
*/
public static List<User> sortUserList(List<User> originalList,Comparator comparator){
List<User> list = (List<User>) originalList.stream().sorted(comparator)
.collect(Collectors.toList());
return list;
}
public static void main(String... args){
//传入名字长度比较器
sortUserList(userList, new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
return u1.getName().length()>u2.getName().length()?1:-1;
}
}).forEach(u->System.out.println(u.getName()));
}
场景四:
例如如下资金流水变动数据,需要对其按资金变动类型做分组处理
List<CapitalChange> capitalChanges = Stream.of(new CapitalChange("1",new Date(),"IA1", BigDecimal.TEN,"OA1",BigDecimal.TEN),
new CapitalChange("2",new Date(),"IA1", BigDecimal.TEN,"OA1",BigDecimal.TEN),
new CapitalChange("3",new Date(),"IA2", BigDecimal.TEN,"OA2",BigDecimal.TEN),
new CapitalChange("3",new Date(),"IA1", BigDecimal.TEN,"OA1",BigDecimal.TEN),
new CapitalChange("3",new Date(),"IA3", BigDecimal.TEN,"OA3",BigDecimal.TEN),
new CapitalChange("1",new Date(),"IA1", BigDecimal.TEN,"OA1",BigDecimal.TEN))
.collect(Collectors.toList());
分组代码非常简单,一行足以
/* @description: 对集合中的数据进行分组,例如根据资金变动的类型来分组
* @author: Sherwin Liang
* @timestamp: 2021/11/5 23:10
* @param: capitalChanges 需分组的数据
* @return: Map<String, List<CapitalChange>> 分组结果
*/
public static Map<String, List<CapitalChange>> groupCapitalChanges(List<CapitalChange> capitalChanges){
return capitalChanges.stream().collect(Collectors.groupingBy(c->c.getChangeType()));
}