如何使用两种排序对 ArrayList 进行排序 [英] How to sort an ArrayList using two sorts
问题描述
我有一个包含性别的名字列表,以及有多少人拥有这个名字.
I have a list of names that have the gender and a count of how many people have that name.
例如:
约翰 M 600
迈克 M 200
莎拉 F 700
汤姆 M 400
艾米丽 F 600
克里斯 M 600
我正在尝试按计数降序对名称进行排序,如果它们具有相同的计数,我希望它们按 ABC 顺序排序.我单独制作的函数按 ABC 顺序打印计数,然后按降序打印另一个.
I am trying to sort the names in descending order by the count and if they have the same count i want them to be sorted in ABC order. Function I made separately prints the count in ABC order and than prints another that is in descending order .
示例:发生了什么
克里斯 M 600
艾米丽 F 600
迈克 M 200
约翰 M 600
莎拉 F 700
汤姆 M 400
莎拉 F 700
约翰 M 600
艾米丽 F 600
克里斯 M 600
汤姆 M 400
迈克 M 200
我想得到什么
莎拉 F 700
克里斯 M 600
艾米丽 F 600
约翰 M 600
汤姆 M 400
迈克 M 200
ArrayList<OneName> oneName = new ArrayList<OneName>();
while(sc.hasNextLine())
{
// read a line from the input file via sc into line
line = sc.nextLine();
StringTokenizer stk = new StringTokenizer(line, ",");
String name = stk.nextToken();
char sex = stk.nextToken().charAt(0);
int count = Integer.parseInt(stk.nextToken());
OneName list = new OneName(name, sex, count);
oneName.add(list);
} Collections.sort(oneName, new OneNameCompare());
for(OneName a: oneName)
{
System.out.println(a.toString());
}
Collections.sort(oneName, new OneNameCountCompare());
for(OneName b: oneName)
{
System.out.println(b.toString());
}
OneNameCompare.java
import java.util.Comparator;
import java.util.Collections;
public class OneNameCompare implements Comparator<OneName>
{
public int compare(OneName a1, OneName a2)
{
return a1.getName().compareTo(a2.getName());
}
}
OneNameCountCompare.java
import java.util.Comparator;
import java.util.Collections;
public class OneNameCountCompare implements Comparator<OneName>
{
{
if(b1.getCount() < b2.getCount())
{
return 1;
}
else
{
return -1;
}
}
}
推荐答案
Java 8 解决方案
您可以通过 thenComparing(Comparator super T> other)
Java 8 中引入 Comparator 的方法.
Java 8 solution
You can combine both comparators via thenComparing(Comparator<? super T> other)
method introduced to Comparator in Java 8.
所以代替
Collections.sort(oneName, new OneNameCompare());
for (OneName a : oneName) {
System.out.println(a.toString());
}
Collections.sort(oneName, new OneNameCountCompare());
for (OneName b : oneName) {
System.out.println(b.toString());
}
使用
Collections.sort(oneName, new OneNameCountCompare()
.thenComparing(new OneNameCompare()));
for (OneName b : oneName) {
System.out.println(b.toString());
}
顺便说一句,您似乎可以简化"您的代码使用名为 方法参考的新 Java 8 功能一点点只需创建所需的比较器.
BTW it seems that you can "simplify" your code a little using new Java 8 features called method references to simply create required Comparators.
import static java.util.Comparator.comparing;
//...
Comparator<OneName> reversedCountComparator = comparing(OneName::getCount).reversed();
Comparator<OneName> nameComparator = comparing(OneName::getName);
oneName.sort(reversedCountComparator.thenComparing(nameComparator));
oneName.forEach(System.out::println);
Java 7 解决方案.
因为 Collections.sort(collection,comparator)
只接受一个比较器,所以你需要创建一个类来实现 Comparator,但会在内部使用你的其他比较器.这样的类的代码可以是这样的
Java 7 solution.
Since Collections.sort(collection, comparator)
accept only one comparator you need to create class which will implement Comparator, but will internally use your other comparators. Code of such class can look like
class ComparatorsMixer<T> implements Comparator<T> {
List<Comparator<T>> comparatorsList;
public ComparatorsMixer(List<Comparator<T>> list) {
this.comparatorsList = list;
}
public ComparatorsMixer() {
comparatorsList = new ArrayList<>();
}
public void addComparator(Comparator<T> comparator){
comparatorsList.add(comparator);
}
public int compare(T o1, T o2) {
for (Comparator<T> c : comparatorsList) {
int result = c.compare(o1, o2);
if (result != 0)
return result;
//if result == 0 then move on to next comparator
}
return 0;
}
}
你可以像这样使用它
ComparatorsMixer<OneName> mix = new ComparatorsMixer<>();
mix.addComparator(new OneNameCountCompare());
mix.addComparator(new OneNameCompare());
Collections.sort(oneName, mix);
这篇关于如何使用两种排序对 ArrayList 进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!