場景:
奧運會時期,每場賽過後,對國家的金、銀、銅牌進行排序,排序規則以下:
先以金牌排序,金牌數越多,排得越前,若是金牌數相同,則比銀牌數,若是銀牌數同樣多,則比銅牌數,若是銅牌數還同樣多,則按國家英文字母順序升序排序。
例如:
China 51 20 21
American 50 1 1
Japan 0 0 0
上面是三個國家的獎牌數,每一行依次是國家名、金牌數、銀牌數、銅牌數。java
需求:
請將獎牌按上面規則進行排序。算法
Java的一個實現:能夠使用Stream進行多字段排序。測試
代碼:this
import junit.framework.TestCase; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class Medal { private String country; // 國家 private int gi; // 金牌數量 private int si; // 銀牌數量 private int bi; // 銅牌數量 public Medal() { } public Medal(String country, int gi, int si, int bi) { this.country = country; this.gi = gi; this.si = si; this.bi = bi; } public String getCountry() { return country; } public int getGi() { return gi; } public int getSi() { return si; } public int getBi() { return bi; } /** * 使用Stream進行多字段排序 * * @param paramArray * @return */ public static List<String> rankByStream(String[] paramArray) { return Arrays.stream(paramArray).map(e -> { String[] array = e.split(" "); return new Medal(array[0], Integer.valueOf(array[1]), Integer.valueOf(array[2]), Integer.valueOf(array[3])); }).sorted(Comparator.comparing(Medal::getGi, Comparator.reverseOrder()) .thenComparing(Medal::getSi, Comparator.reverseOrder()) .thenComparing(Medal::getBi, Comparator.reverseOrder()) .thenComparing(Medal::getCountry)).map(Medal::getCountry).collect(Collectors.toList()); } public static void main(String[] args) { String[] testParam1 = new String[]{"China 51 20 21", "American 50 1 1", "Japan 0 0 0"}; // 測試用例1 入參 List<String> expected1 = Arrays.asList("China", "American", "Japan"); // 測試用例1 返回結果 String[] testParam2 = new String[]{"China 51 20 21", "American 52 1 1", "Japan 0 0 0"}; List<String> expected2 = Arrays.asList("American", "China", "Japan"); String[] testParam3 = new String[]{"China 51 20 21", "American 51 20 22", "Japan 53 0 0"}; List<String> expected3 = Arrays.asList("Japan", "American", "China"); String[] testParam4 = new String[]{"China 51 20 21", "American 50 1 1", "Japan 0 0 0", "France 51 20 20"}; List<String> expected4 = Arrays.asList("China", "France", "American", "Japan"); TestCase.assertEquals(expected1, Medal.rankByStream(testParam1)); TestCase.assertEquals(expected2, Medal.rankByStream(testParam2)); TestCase.assertEquals(expected3, Medal.rankByStream(testParam3)); TestCase.assertEquals(expected4, Medal.rankByStream(testParam4)); } }
運行main方法,相關的測試案例均經過,返回結果與預期一致。code
裏面的核心方法是:stream.sorted(...).thenComparing(...),在咱們這個例子中,須要進行四組排序,而後獲得最後結果。排序
Stream不是一個集合,是一個流式的計算實現。
使用Stream.sorted(...).thenComparing(...),能夠實現多字段的排序。
Stream是惰性求值,所以sorted、thenComparing等是在進行使用集合類進行存儲時,纔會真正進行計算而後放入對應的容器。get
那麼stream的排序機制又是什麼樣的呢?與咱們經典冒泡等八大排序法有什麼區別,Stream究竟是有沒有自創出新的排序算法,仍是說只是使用八大排序法之一進行了封裝?it
下一篇將對Stream在多字段排序時的時間複雜度進行分析。class