如何使用两种排序方式对ArrayList进行排序 [英] How to sort an ArrayList using two sorts

查看:59
本文介绍了如何使用两种排序方式对ArrayList进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有性别的名字列表,以及有多少人使用该名字.

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

Emily F 600

Emily 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

Emily F 600

Emily F 600

迈克M 200

约翰M 600

萨拉F 700

汤姆M 400

萨拉F 700

约翰M 600

Emily F 600

Emily F 600

克里斯M 600

汤姆M 400

迈克M 200

我想要得到的东西

萨拉F 700

克里斯M 600

Emily F 600

Emily 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>其他) 方法在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的类,但将在内部使用其他比较器.这样的代码看起来像


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆