我实际上能够仅根据键和值对Map
进行排序,我什至尝试像下面这样对它们进行排序:
我根据国家对学生进行排序,如果两个学生碰巧有相同的states
则仅在匹配的国家中按StudentID
排序。
到目前为止我尝试过:
final Map<Integer, String> studentMaster = new HashMap<>() {{
put(146, "Sweden");
put(148, "Sweden");
put(110, "Orebro");
put(6, "Malmo");
put(14, "Orebro");
put(26, "Malmo");
}
};
studentMaster.entrySet().stream()
.sorted((i1,i2)->i1.getValue().compareTo(i2.getValue()))
.sorted((j1,j2)->j1.getKey().compareTo(j2.getKey()))
.forEach(System.out::println);
我得到的结果**(实际输出)**
14=Orebro
26=Malmo
110=Orebro
146=Sweden
148=Sweden
预期输出:
26=Malmo
14=Orebro
110=Orebro
146=Sweden
148=Sweden
注意:您的预期输出和实际输出与您添加到Map
的键不匹配。
代码不起作用的原因是,您使用两个单独的Comparator
调用Stream#sorted
两次,因此对Stream#sorted
的第一次调用在您的情况下是无用的(因为它被第二次调用覆盖)。
我能够通过将自定义Comparator
传递给Stream#sorted
来实现您的预期输出:
Map.Entry.<Integer, String>comparingByValue()
.thenComparing(Map.Entry.comparingByKey())
输出:
6=Malmo
26=Malmo
14=Orebro
110=Orebro
146=Sweden
148=Sweden
前段时间我回答了如何在java中将名称与年龄一起排序,除了用于存储的数据结构之外,与您的问题有许多相似之处。遍历每个键并对其进行排序,然后在值中再次排序,然后对其进行排序是非常乏味的,并且会让您感到非常困惑。只要记住你以前如何使用 Map 时是如何遍历的 Map :
for (Map.Entry<String,String> entry : somemap.entrySet()){..Some Statements..};
studentMaster.entrySet().stream()
.sorted(Comparator.comparing((Map.Entry<Integer, String> m) -> m.getValue())
.thenComparing(Map.Entry::getKey)).forEach(System.out::println);
输出
6=Malmo
26=Malmo
14=Orebro
110=Orebro
146=Sweden
148=Sweden
<</div>
div class="one_answers"> Comparator
应如下所示:
Comparator<Entry<Integer, String>> comparator = (o1, o2) -> {
int i = o1.getValue().compareTo(o2.getValue());
if (i == 0) {
return o1.getKey().compareTo(o2.getKey());
} else {
return i;
}
};
然后将其传递给Stream#sorted
方法:studentMaster.entrySet().stream().sorted(comparator).forEach(System.out::println);
输出:
6=Malmo
26=Malmo
14=Orebro
110=Orebro
146=Sweden
148=Sweden
2 种方式:
- 将
TreeSet
与Comparable
pojo一起使用。 - 将
TreeSet
与自定义Comparator
一起使用。
法典
啧啧.java
(将TreeSet
与Comparable
pojo一起使用。
import java.util.*;
public class Tmp {
static class StudentMaster implements Comparable<StudentMaster> {
private Integer id;
private String master;
public StudentMaster(Integer id, String master) {
this.id = id;
this.master = master;
}
@Override
public int compareTo(StudentMaster other) {
int masterFlag = master.compareTo(other.master);
return (masterFlag == 0) ? id.compareTo(other.id) : masterFlag;
}
@Override
public boolean equals(Object o) {
StudentMaster osm = (StudentMaster) o;
return id == osm.id && master.equals(osm.master);
}
@Override
public int hashCode() {
return Objects.hash(id, master);
}
public String toString() {
StringBuilder sb = new StringBuilder();
Formatter fm = new Formatter(sb);
fm.format("id = %d, master = %sn", id, master);
fm.close();
return sb.toString();
}
}
public static void test() {
final Set<StudentMaster> smSet = new TreeSet<>();
smSet.add(new StudentMaster(146, "Sweden"));
smSet.add(new StudentMaster(148, "Sweden"));
smSet.add(new StudentMaster(110, "Orebro"));
smSet.add(new StudentMaster(6, "Malmo"));
smSet.add(new StudentMaster(14, "Orebro"));
smSet.add(new StudentMaster(26, "Malmo"));
for (StudentMaster sm : smSet) {
System.out.print(sm);
}
}
public static void main(String[] args) {
test();
}
}
Tmp比较器.java
(将TreeSet
与自定义Comparator
一起使用。
import java.util.*;
public class TmpComparator {
static Comparator<StudentMaster> smc = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
StudentMaster sm1 = (StudentMaster) o1, sm2 = (StudentMaster) o2;
int masterFlag = sm1.master.compareTo(sm2.master);
return (masterFlag == 0) ? sm1.id.compareTo(sm2.id) : masterFlag;
}
};
static class StudentMaster {
private Integer id;
private String master;
public StudentMaster(Integer id, String master) {
this.id = id;
this.master = master;
}
@Override
public boolean equals(Object o) {
StudentMaster osm = (StudentMaster) o;
return id == osm.id && master.equals(osm.master);
}
@Override
public int hashCode() {
return Objects.hash(id, master);
}
public String toString() {
StringBuilder sb = new StringBuilder();
Formatter fm = new Formatter(sb);
fm.format("id = %d, master = %sn", id, master);
fm.close();
return sb.toString();
}
}
public static void test() {
final Set<StudentMaster> smSet = new TreeSet<>(smc);
smSet.add(new StudentMaster(146, "Sweden"));
smSet.add(new StudentMaster(148, "Sweden"));
smSet.add(new StudentMaster(110, "Orebro"));
smSet.add(new StudentMaster(6, "Malmo"));
smSet.add(new StudentMaster(14, "Orebro"));
smSet.add(new StudentMaster(26, "Malmo"));
for (StudentMaster sm : smSet) {
System.out.print(sm);
}
}
public static void main(String[] args) {
test();
}
}
只需运行main()
方法。
两者的输出是相同的:
id = 6, master = Malmo
id = 26, master = Malmo
id = 14, master = Orebro
id = 110, master = Orebro
id = 146, master = Sweden
id = 148, master = Sweden
技巧
- 在生产代码中,
equals()
需要改进,这是一个简化版本,仅用于测试。