如何将具有两组元素的列表排序为两个按字母顺序排列的列表

时间:2013-04-02 09:33:47

标签: java list sorting comparator

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

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

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

无论是排序类型,它应始终将最终列表显示为列表第一部分中的付费项目,列表第二部分中的空闲项目以及基于比较器排序的列表中的每个集合(Az或ZA..etc)。

Foe eg。

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

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


使用代码段进行更新:

该列表包含名称为{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} ..

3 个答案:

答案 0 :(得分:1)

您可以尝试using a second parameter als Comperator

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

使用该comperator,您可以对列表进行排序。

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);

答案 1 :(得分:1)

我能想到的一种方式是:

像这样修改每个比较器:

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

//算法

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

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

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

修改:

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

public static class 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;
    }

答案 2 :(得分:0)

  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
    }