簡體   English   中英

根據作為arraylist java 8的值對地圖進行排序

[英]Sort a map based on value which is an arraylist java 8

我有一個 Hashmap map<String, List<Student>>

Student {
  String name;
  List<Date> absentDates;
}

鍵值對如下:

["Class1",<Student1  absentDates = [02/11/2010, 02/09/2010]><Student2  absentDates = [02/10/2010]>]
["Class2",<Student3  absentDates = [02/12/2010]>]
["Class3",<Student4  absentDates = null>]

我如何使用 java 8 steams 對這張地圖進行排序,如下所示,基於地圖值,即 List.get(0).getAbsentDates().get(0) 即,每個列表中第一個 Student 對象的可為空的缺席日期

預期輸出是

["Class2",<Student3  absentDates = [02/12/2010]>]
["Class1",<Student1  absentDates = [02/11/2010, 02/09/2010]><Student2  absentDates = [02/10/2010]>]
["Class3",<Student4  absentDates = null>]

我遵循的步驟。

  1. Map<String, List> 通過 entrySet 流
  2. 轉換為類 MapValues{Key,List}。 MapValue 是為保存鍵和值而創建的自定義包裝類
  3. 基於 stundents.get(0).getAbsentDates().get(0) 為 MapValues 實現 Comaparator 並在 comaprator 中處理 null
  4. 使用 Collectors.toMap 收集以使用 LinkedHashMap 保留順序

總之

Map<String, List<Student>> newmap = map.entrySet()
                                                .stream()
                                                .map(e -> new MapValues(e.getKey(), e.getValue()))
                                                .sorted(new MapValuesComp())
                                                .collect(Collectors.toMap(
                                                 MapValues::getKey, MapValues::getStdns, 
                                                             (e1, e2) -> e1, 
                                                            LinkedHashMap::new));
public class CustomMapSorting {
    public static void main(String[] args) throws ParseException {

        Map<String, List<Student>> map = new HashMap<>();
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        // Class1 Stundent1
        Date s1Date1 = format.parse("02/11/2010");
        Date s1Date2 = format.parse("02/09/2010");

        Date[] s1absentDates = { s1Date1, s1Date2 };
        Student s1 = new Student("Student1", Arrays.asList(s1absentDates));
        // Class1 Stundent2
        Date s2Date1 = format.parse("02/10/2010");

        Date[] s2absentDates = { s2Date1 };
        Student s2 = new Student("Student2", Arrays.asList(s2absentDates));

        // Class2 Stundent3

        Date s3Date1 = format.parse("02/12/2010");

        Date[] s3absentDates = { s3Date1 };
        Student s3 = new Student("Student3", Arrays.asList(s3absentDates));

        // Class3 Stundent4

        Student s4 = new Student("Stundent4", null);

        List<Student> class1SundLst = Arrays.asList(s1, s2);
        map.put("Class1", class1SundLst);
        map.put("Class2", Arrays.asList(s3));
        map.put("Class3", Arrays.asList(s4));

        Map<String, List<Student>> newmap = map.entrySet()
                                                .stream()
                                                .map(e -> new MapValues(e.getKey(), e.getValue()))
                                                .sorted(new MapValuesComp())
                                                .collect(Collectors.toMap(MapValues::getKey, MapValues::getStdns, (e1, e2) -> e1, LinkedHashMap::new));
        //Printing the sorted values
        newmap.entrySet().stream().forEach(e -> System.out.println(e.getKey() + " : " + e.getValue().get(0).absentDates));

    }

}

class MapValues {
    String key;
    List<Student> stdns;

    public MapValues(String key, List<Student> stdns) {
        super();
        this.key = key;
        this.stdns = stdns;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public List<Student> getStdns() {
        return stdns;
    }

    public void setStdns(List<Student> stdns) {
        this.stdns = stdns;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return key;
    }

}

class MapValuesComp implements Comparator<MapValues> {

    public int compare(MapValues o1, MapValues o2) {
        if (o1.stdns.get(0).absentDates == null) {
            return (o2.stdns.get(0).absentDates == null) ? 0 : 1;
        }
        if (o2.stdns.get(0).absentDates == null) {
            return 1;
        }
        return o2.stdns.get(0).absentDates.get(0).compareTo(o1.stdns.get(0).absentDates.get(0));

    }

}

class Student {
    String name;
    List<Date> absentDates;

    public Student(String name, List<Date> absentDates) {
        super();
        this.name = name;
        this.absentDates = absentDates;
    }

    @Override
    public String toString() {
        if (absentDates == null)
            return null;
        SimpleDateFormat format = new SimpleDateFormat("dd/mm/YYYY");
        return format.format(absentDates.get(0));
    }

}

我嘗試了使用@Rono 發布的答案中的 lambda 表達式的內聯解決方案。 只是他的解決方案的改進版本。

Map<String, List<Student>> res = map.entrySet()
        .stream()
        .sorted((o1, o2) -> {
            if (o1.getValue().get(0).absentDates == null) {
                return (o2.getValue().get(0).absentDates == null) ? 0 : 1;
            }
            if (o2.getValue().get(0).absentDates == null) {
                return 1;
            }
            return o2.getValue().get(0).absentDates.get(0).compareTo(o1.getValue().get(0).absentDates.get(0));
        }).
        collect(Collectors.toMap(Map.Entry::getKey, 
                Map.Entry::getValue,(e1, e2) -> e1, 
                LinkedHashMap::new));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM