2017-03-19 33 views
4

遞增有一個表,現在添加一個新的列 - 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:[email protected]+1) where level = 1 order by id; 
set @index:=0; update t set sort_num = (@index:[email protected]+1) where level = 2 order by id; 
set @index:=0; update t set sort_num = (@index:[email protected]+1) where level = 3 order by id; 
+1

如果你的意思是'Stream'而不是'Java 8',那麼我會說不。因爲有些國家依賴於已經看過的元素。 – Flown

回答

2

最好的方法是堅持你的普通增強for循環。我不認爲有可能拿出一個單獨的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)) 
); 
0

如果您自己跟蹤下一個訂單號,您可以使用一個流來完成。該解決方案是線程安全的爲好,因此應與平行流工作:

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

應該優於其他流的解決方案,因爲它需要唯一的遍歷列表。

+0

@Flown:我不明白爲什麼我提供的解決方案確實依賴於任何訂單?是否重要/是否需要考慮'id'? – Harmlezz

+0

因此,我應該將'forEach'換成'forEachOrdered',它可以糾正解決方案,但會犧牲性能(從未請求過)。 – Harmlezz