Sort a map based on value which is an ArrayList java 8

huangapple go评论73阅读模式
英文:

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 流对此映射进行排序,排序基于映射值即 List<Student>。get(0).getAbsentDates().get(0),即每个列表中第一个 Student 对象的可为空的 absentDates

期望输出为

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

I have a Hashmap map&lt;String, List&lt;Student&gt;&gt;.

Student {
  String name;
  List&lt;Date&gt; absentDates;
}

Key Values pairs as follows:

[&quot;Class1&quot;,&lt;Student1  absentDates = [02/11/2010, 02/09/2010]&gt;&lt;Student2  absentDates = [02/10/2010]&gt;]
[&quot;Class2&quot;,&lt;Student3  absentDates = [02/12/2010]&gt;]
[&quot;Class3&quot;,&lt;Student4  absentDates = null&gt;]

How can I sort this map using java 8 steams as follows, based on map value ie, List<Student>.get(0).getAbsentDates().get(0) ie, a nullable absentDates of first Student object in each list

Expected output is

[&quot;Class2&quot;,&lt;Student3  absentDates = [02/12/2010]&gt;]
[&quot;Class1&quot;,&lt;Student1  absentDates = [02/11/2010, 02/09/2010]&gt;&lt;Student2  absentDates = [02/10/2010]&gt;]
[&quot;Class3&quot;,&lt;Student4  absentDates = null&gt;]

答案1

得分: 1

步骤我所遵循的

1. 使用entrySet遍历Map&lt;String, List&lt;Student&gt;&gt;
2. 转换为MapValues类{Key,List&lt;Stundent&gt;}MapValue是自定义的包装类用于保存键和值
3. 为MapValues实现比较器基于stundents.get(0).getAbsentDates().get(0)同时处理比较器中的null
4. 使用Collectors.toMap进行收集以保留顺序使用LinkedHashMap

简而言之

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

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

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

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

		// Class2 Stundent3

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

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

		// Class3 Stundent4

		Student s4 = new Student(&quot;Stundent4&quot;, null);

		List&lt;Student&gt; class1SundLst = Arrays.asList(s1, s2);
		map.put(&quot;Class1&quot;, class1SundLst);
		map.put(&quot;Class2&quot;, Arrays.asList(s3));
		map.put(&quot;Class3&quot;, Arrays.asList(s4));

		Map&lt;String, List&lt;Student&gt;&gt; newmap = map.entrySet()
												.stream()
												.map(e -&gt; new MapValues(e.getKey(), e.getValue()))
												.sorted(new MapValuesComp())
												.collect(Collectors.toMap(MapValues::getKey, MapValues::getStdns, (e1, e2) -&gt; e1, LinkedHashMap::new));
		// 打印排序后的值
		newmap.entrySet().stream().forEach(e -&gt; System.out.println(e.getKey() + &quot; : &quot; + e.getValue().get(0).absentDates));

	}

}

class MapValues {
	String key;
	List&lt;Student&gt; stdns;

	public MapValues(String key, List&lt;Student&gt; stdns) {
		super();
		this.key = key;
		this.stdns = stdns;
	}

	public String getKey() {
		return key;
	}

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

	public List&lt;Student&gt; getStdns() {
		return stdns;
	}

	public void setStdns(List&lt;Student&gt; stdns) {
		this.stdns = stdns;
	}

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

}

class MapValuesComp implements Comparator&lt;MapValues&gt; {

	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&lt;Date&gt; absentDates;

	public Student(String name, List&lt;Date&gt; absentDates) {
		super();
		this.name = name;
		this.absentDates = absentDates;
	}

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

}
英文:

Steps I followed.

  1. Map<String, List<Student>> Stream through the entrySet
  2. convert to class MapValues{Key,List<Stundent>}. MapValue is the Custom wrapper class created to hold key and value
  3. Implement Comaparator for MapValues based on stundents.get(0).getAbsentDates().get(0) and also handle null in comaprator
  4. Collect using Collectors.toMap to preserve the order use LinkedHashMap

In Short the

Map&lt;String, List&lt;Student&gt;&gt; newmap = map.entrySet()
.stream()
.map(e -&gt; new MapValues(e.getKey(), e.getValue()))
.sorted(new MapValuesComp())
.collect(Collectors.toMap(
MapValues::getKey, MapValues::getStdns, 
(e1, e2) -&gt; e1, 
LinkedHashMap::new));
public class CustomMapSorting {
public static void main(String[] args) throws ParseException {
Map&lt;String, List&lt;Student&gt;&gt; map = new HashMap&lt;&gt;();
SimpleDateFormat format = new SimpleDateFormat(&quot;dd/MM/yyyy&quot;);
// Class1 Stundent1
Date s1Date1 = format.parse(&quot;02/11/2010&quot;);
Date s1Date2 = format.parse(&quot;02/09/2010&quot;);
Date[] s1absentDates = { s1Date1, s1Date2 };
Student s1 = new Student(&quot;Student1&quot;, Arrays.asList(s1absentDates));
// Class1 Stundent2
Date s2Date1 = format.parse(&quot;02/10/2010&quot;);
Date[] s2absentDates = { s2Date1 };
Student s2 = new Student(&quot;Student2&quot;, Arrays.asList(s2absentDates));
// Class2 Stundent3
Date s3Date1 = format.parse(&quot;02/12/2010&quot;);
Date[] s3absentDates = { s3Date1 };
Student s3 = new Student(&quot;Student3&quot;, Arrays.asList(s3absentDates));
// Class3 Stundent4
Student s4 = new Student(&quot;Stundent4&quot;, null);
List&lt;Student&gt; class1SundLst = Arrays.asList(s1, s2);
map.put(&quot;Class1&quot;, class1SundLst);
map.put(&quot;Class2&quot;, Arrays.asList(s3));
map.put(&quot;Class3&quot;, Arrays.asList(s4));
Map&lt;String, List&lt;Student&gt;&gt; newmap = map.entrySet()
.stream()
.map(e -&gt; new MapValues(e.getKey(), e.getValue()))
.sorted(new MapValuesComp())
.collect(Collectors.toMap(MapValues::getKey, MapValues::getStdns, (e1, e2) -&gt; e1, LinkedHashMap::new));
//Printing the sorted values
newmap.entrySet().stream().forEach(e -&gt; System.out.println(e.getKey() + &quot; : &quot; + e.getValue().get(0).absentDates));
}
}
class MapValues {
String key;
List&lt;Student&gt; stdns;
public MapValues(String key, List&lt;Student&gt; stdns) {
super();
this.key = key;
this.stdns = stdns;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public List&lt;Student&gt; getStdns() {
return stdns;
}
public void setStdns(List&lt;Student&gt; stdns) {
this.stdns = stdns;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return key;
}
}
class MapValuesComp implements Comparator&lt;MapValues&gt; {
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&lt;Date&gt; absentDates;
public Student(String name, List&lt;Date&gt; absentDates) {
super();
this.name = name;
this.absentDates = absentDates;
}
@Override
public String toString() {
if (absentDates == null)
return null;
SimpleDateFormat format = new SimpleDateFormat(&quot;dd/mm/YYYY&quot;);
return format.format(absentDates.get(0));
}
}

答案2

得分: 1

我尝试了使用来自@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));
英文:

I tried a inline solution using lambdas from the answer posted using @Rono. Just a improved version of his solution.

Map&lt;String, List&lt;Student&gt;&gt; res = map.entrySet()
.stream()
.sorted((o1, o2) -&gt; {
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) -&gt; e1, 
LinkedHashMap::new));

huangapple
  • 本文由 发表于 2020年9月17日 02:44:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63926190.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定