【问题标题】:How to sort a list which has two set of elements into two alphabetically ordered sets list如何将具有两组元素的列表排序为两个按字母顺序排列的集合列表
【发布时间】:2013-03-23 13:05:12
【问题描述】:

我有一个包含两种元素的列表 - 免费项目和付费项目。

我想对列表进行排序,使付费项目位于列表的第一部分,而免费项目位于列表的第二部分。

我有一组比较器,例如 A-Z 排序、Z-A 排序、类型排序。

无论是哪种排序类型,它都应始终在列表的第一部分显示最终列表为付费项目,在列表的第二部分显示免费项目,并且列表中的每个集合都根据比较器(Az或 ZA..等)。

敌人例如。

我有三个付费项目和五个免费项目。
当我按 A-Z 对完整列表进行排序时,它应该按 A-Z 排序显示三个付费项目,然后按 A-Z 排序顺序显示免费项目。

我想知道如何实现这一点。


使用代码 sn-ps 更新:

列表包含名称为 {APaid、MFree、OFree、BPaid、NFree、PFree、CPaid、QFree} 的项目

Collections.sort(myList, new UtilityClass.TitleComparatorAtoZ());  

public static class TitleComparatorAtoZ implements Comparator
    {

        public int compare(Object o1, Object o2)
        {
            int result = 0;

            if ((o1 != null) && (o2 != null))
            {
                if (o1 instanceof Item && o2 instanceof Item)
                {
                    Item lmi1 = (Item) o1;
                    Item lmi2 = (Item) o2;

                    if ((lmi1.getName() != null) && (lmi2.getName() != null))
                    {
                        result = lmi1.getName().compareToIgnoreCase(lmi2.getName());
                    }
                }
            }
            return result;
        }
    }

最后的列表应该是{APaid, BPaid, CPaid, MFree, NFree, OFree, PFree, QFree}..

【问题讨论】:

    标签: java list sorting comparator


    【解决方案1】:

    我能想到的一种方法是:

    像这样修改每个比较器:

    首先根据是付费还是免费项目比较两个对象参数,然后根据A-Z等进行比较...

    //算法

    比较器(对象 T1,对象 T2) 开始

    如果 T1 已付款且 T2 是免费的,则返回 1 否则,如果 T1 是免费的并且 T2 是付费的,则返回 -1 else //两者都是免费或付费,然后根据A-Z起始字符进行比较 返回(比较起始字符)。

    所以,如果您有一个以 Z 开头的付费项目,那么它将在以 A 开头的付费项目之后。

    修改:

    Collections.sort(myList, new UtilityClass.TitleComparatorAtoZ());

    公共静态类 TitleComparatorAtoZ 实现 Comparator {

        public int compare(Object o1, Object o2)
        {
            int result = 0;
    
            if ((o1 != null) && (o2 != null))
            {
                if (o1 instanceof Item && o2 instanceof Item)
                {
                    Item lmi1 = (Item) o1;
                    Item lmi2 = (Item) o2;
    
                    if ((lmi1.getName() != null) && (lmi2.getName() != null))
                    {
                        if(lmi1.getName().endsWith("Paid") 
                           && lmi2.getName().endsWith("Free")) 
                        {
                             result = 1;
                        }
                        else if (lmi1.getName().endsWith("Free") 
                           && lmi2.getName().endsWith("Paid"))
                        {
                             result = -1;
                        }
                        else
                        {
                             result = lmi1.getName().compareToIgnoreCase(lmi2.getName());
    
                        }
    
                                            }
                }
            }
            return result;
        }
    

    【讨论】:

    • 能否请您详细说明我的代码 sn-p,我应该如何修改比较器。
    【解决方案2】:

    你可以试试using a second parameter als Comperator

    它允许你传递一个 Comparator 的实例来根据你的需要进行排序。例如,您可以创建一个比较器来检查所有对象的变量Name,或者创建一个比较器来检查变量Type

    使用该比较器,您可以对列表进行排序。

    public static <T> void sort(List<T> list,
                                Comparator<? super T> c)
    

    There is a nice and easy example of this here.

    例如,您有类Fruit。你可以在这个类中加入如下代码:

    public static Comparator<Fruit> FruitNameComparator 
                          = new Comparator<Fruit>() {
    
        public int compare(Fruit fruit1, Fruit fruit2) {
    
          String fruitName1 = fruit1.getFruitName().toUpperCase();
          String fruitName2 = fruit2.getFruitName().toUpperCase();
    
          //ascending order
          return fruitName1.compareTo(fruitName2);
    
          //descending order
          //return fruitName2.compareTo(fruitName1);
        }
    
    };
    

    使用该代码,您可以在任何地方比较水果的名称 Arrays.sort(fruits, Fruit.FruitNameComparator);

    【讨论】:

      【解决方案3】:
      1. 将您的列表分类为哪些是免费项目,哪些是付费项目到 2 个单独的列表中

        for ( X x : list ) {
            if ( isFreeItem ) {
                add to freeItemList
            } else {
                add to paidItemList
            }
        }
        
      2. 使用您的比较器类分别对每个列表进行排序

        Collections.sort(freeItemsList);
        Collections.sort(paidItemsList);
        
      3. 实例化一个新列表并相应地放置您的paidItemsList 和 freeItemsList

        List result = new ArrayList();
        for ( X x : paidItemsList ) {
            add to result
        }
        
        for ( X x : freeItemsList ) {
            add to result
        }
        

      【讨论】:

      • 这是个好主意,但我不想通过创建两个列表然后排序然后合并它们来创建开销。我正在寻找像 Shreyas 所说的 stackoverflow.com/a/15760975/449378 这样的东西。
      猜你喜欢
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2023-02-17
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多