繁体   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