如何按组递增

时间:2017-03-19 12:45:51

标签: java-8

有一个表格,现在添加一个新列 - sort_num int default 0

id  level   sort_num
1   1   0
2   1   0
3   2   0
4   2   0
5   2   0
6   3   0
7   3   0
8   3   0
9   3   0

现在我想设置sort_num值,如下所示

id  level   sort_num
1   1   1
2   1   2
3   2   1
4   2   2
5   2   3
6   3   1
7   3   2
8   3   3
9   3   4

上面的Java代码实现要求是

    int sortNum = 0;
    int currentLevel = fooList.get(0).getLevel();
    for (RuleConf foo : fooList) {
        if(currentLevel != foo.getLevel()){
            sortNum = 0;
            currentLevel = foo.getLevel();
        }
        foo.setSortNum(++sortNum);
    }

我想知道Java8是否可以简化上述代码?

PS。使用mysql来实现此要求

set @index:=0; update t set sort_num = (@index:=@index+1) where level = 1 order by id;
set @index:=0; update t set sort_num = (@index:=@index+1) where level = 2 order by id;
set @index:=0; update t set sort_num = (@index:=@index+1) where level = 3 order by id;

2 个答案:

答案 0 :(得分:2)

最好的方法是坚持使用普通的增强型循环。我不认为有可能提出一个Stream解决方案,因为您需要具有中间值。像:

Map<Integer, List<RuleConf>> levels = fooList.stream()
    .collect(Collectors.groupingBy(RuleConf::getLevel));
levels.values().forEach(v -> 
    IntStream.range(0, v.size()).forEach(i -> v.get(i).setSortNum(i + 1))
);

答案 1 :(得分:0)

如果您自己跟踪下一个订单号,可以使用一个流来完成。此解决方案也是线程安全的,因此应该使用并行流:

Map<Integer, AtomicInteger> orders = new ConcurrentHashMap<>();
fooList.stream().forEachOrdered(foo -> {
    orders.putIfAbsent(foo.getLevel(), new AtomicInteger());
    foo.setOrder(orders.get(foo.getLevel()).incrementAndGet());
});

它应该胜过其他流解决方案,因为它只需要遍历列表中的那些。