我有两个列表并尝试使用每个List中的元素形成一个String,在我执行" "
之间,保持排序顺序。但是,一旦我将"|"
放在中间,我想要的,Set中元素的顺序就会被切换。
如何添加"|"
并仍然维护集students
中的排序顺序?
以下是代码:
Set<String> students = new HashSet<>();
Set<String> fn = new HashSet<>();
Set<String> nums = new HashSet<>();
List<String> firstNames = new ArrayList<>(fn);
Collections.sort(firstNames);
List<String> favNumbers = new ArrayList<>(nums);
Collections.sort(favNumbers);
for(int i=0; i<firstNames.size(); i++) {
students.add(firstNames.get(i) + "|" + favNumbers.get(i));
}
System.out.println(students);
使用... + " " + ...
,订单为[Joshua 4, Lyon 7]
,但如果添加"|"
代替" "
,订单会在我想要的时候变为[Lyon|7, Joshua|4]
为[Joshua|4, Lyon|7]
。
答案 0 :(得分:2)
HashSet
没有提供有关其内容的任何排序保证,使用基础HashMap
生成的任何排序,而这又基于元素的hashCode()
。
当您更改字符串的内容时,您将获得不同的哈希码 - 就这么简单。 HashMap
中的顺序未定义,如果您插入了触发重新哈希的其他元素,则可能会更改。
如果你想要一个有保证订单的集合,你可以使用SortedSet
实现(例如TreeSet
),但是你需要编写一个合适的类并实现合适的{{1} }秒。或者,您可以使用Comparator
,它以插入顺序维护元素,但需要额外的开销。
答案 1 :(得分:2)
您应该使用面向对象的设计,因为Java是面向对象的语言。不要试图将学生的各种功能表示为独立集合,而是创建包含这些功能的Student
POJO。然后,创建自定义比较器,按名称或喜欢的数字排序。
public class Student {
private String firstName;
private String lastName;
private int favNumber;
// getters and setters
public static Comparator<Student> NameComparator
= new Comparator<Student>() {
public int compare(Student s1, Student s2) {
String f1 = s1.getFirstName();
String f2 = s2.getFirstName();
String l1 = s1.getLastName();
String l2 = s2.getLastName();
if (l1.equalsIgnoreCase(l2) {
return f1.toUpperCase().compareTo(f2);
}
else {
return l1.toUpperCase().compareTo(l2);
}
}
};
public static Comparator<Student> FavComparator
= new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return s1.getFavNumber() < s2.getFavNumber();
}
};
}
现在,如果你有一个学生列表List<Student> list
,你可以通过以下方式排序:
Collections.sort(list, Student.NameComparator);
或者,要按喜欢的数字排序,请使用:
Collections.sort(list, Student.FavComparator);
答案 2 :(得分:0)
它不保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。
因此,您不能依赖HashSet
来保留任何类型的订单。
在我看来,您只需要保留插入顺序,在这种情况下,最好不要使用Set
而不是List
,例如,
List<String> students = new ArrayList<>();