如何在字段上使用RuleBasedCollat​​or对Java对象列表进行排序?

时间:2014-11-12 16:16:38

标签: java sorting

我想使用给定的RuleBasedCollator对特定字段上的ArrayList个对象进行排序。

例如,我们有一个Thing个对象列表:

public Thing {
  public String name;
  public String type;
}

List<Thing> things = new ArrayList<Thing>();

RuleBasedCollator ruleBasedCollator = new RuleBasedCollator("< Table < Plate < Fork < Knife");

现在,在创建了Thing个对象并将它们添加到things列表后,我想对此列表进行排序,获取type“table”的第一个内容以及最后的类型“刀”。

有谁知道怎么做?

4 个答案:

答案 0 :(得分:1)

您可以尝试这样的操作,而不是在Comparator的compare方法中使用compareTo,而可以调用RuleBasedCollat​​or的compare。

mQueue.sort((o1, o2) -> {
    if (o1.getDescription().getTitle() != null && o2.getDescription().getTitle() != null) {
        return mRuleBasedCollator.compare(o1.getDescription().getTitle().toString(),
            o2.getDescription().getTitle().toString());
    } else {
        return 0;
    }
});

答案 1 :(得分:0)

据我所知,RuleBaseCollator用于排序String,至少我在Collat​​or类中说的是超类。我会使用比较器,如下所示:

public class ThingSorter {
public enum ThingType{      
    //wanted sort order, sort on ordinal :
    //Table < Plate < Fork < Knife      
    TABLE, PLATE, FORK, KNIFE
}

public static class Thing {
    private String name;
    private ThingType type;

    public Thing(String name, ThingType tt) {
        this.name = name;
        type = tt;          
    }

    public String toString() {
        return name + " [" + type + "]";
    }
}

public static class MyThingComparator implements Comparator<Thing> {
    @Override
    public int compare(Thing t1, Thing t2) {
        return t1.type.ordinal() - t2.type.ordinal();
    }
}
public static class MyReverseThingComparator implements Comparator<Thing> {
    @Override
    public int compare(Thing t1, Thing t2) {
        return t2.type.ordinal() - t1.type.ordinal();
    }
}

public static void main(String[] args) throws ParseException {
    List<Thing> things = new ArrayList<Thing>();
    things.add(new Thing("One", ThingType.KNIFE));
    things.add(new Thing("Two", ThingType.FORK));
    things.add(new Thing("Three", ThingType.PLATE));
    things.add(new Thing("Four", ThingType.TABLE));
    System.out.println("unsorted:\n" + things);

    Collections.sort(things, new MyThingComparable());  
    System.out.println("sorted:\n" + things);

    Collections.sort(things, new MyReverseThingComparable());   
    System.out.println("sorted:\n" + things);
}

}

在这种情况下,名称不涉及排序类型(以及类型中的序数)

答案 2 :(得分:0)

我终于找到了使用TreeMap的解决方案。我使用&#34;类型&#34;键的属性和值的Thing列表。我创建了一个扩展Collat​​or的ListBasedCollat​​or,而不是使用RuleBasedCollat​​or,因为RuleBasedCollat​​or规则适用于字符,但不适用于单词。

public class ListBasedCollator extends Collator {

private List<String> list;

public ListBasedCollator(String[] array) {
    list = Arrays.asList(array);
}

@Override
public int compare(String source, String target) {
    if(!list.contains(target)) {
        return 1;
    }

    if(!list.contains(source)) {
        return -1;
    }

    return Integer.valueOf(list.indexOf(source)).compareTo(Integer.valueOf(list.indexOf(target)));
}

@Override
public CollationKey getCollationKey(String source) {
    return null;
}

@Override
public int hashCode() {
    return 0;
}

}

以下是我构建TreeMap的方法:

String[] sortingList = {"TABLE", "PLATE", "FORK", "KNIFE"};
ListBasedCollator listBasedCollator = new ListBasedCollator(sortingList);
Map<String, List<Thing>> thingMap = new TreeMap<String, List<Thing>>(listBasedCollator);

因此,thingMap将始终使用listBasedCollat​​or按类型排序。 我还可以按字母顺序对每种不同类型的事物列表进行排序。

答案 3 :(得分:0)

您当然可以使用TreeMapenum作为之前的答案建议;一个相当简单的替代方法是使用只是自定义计算器,而不使用enum。如果您使用的是Java 8,则可以将其归结为一行:

Collections.sort(things,
                 (Thing t1, Thing t2)->ruleBasedCollator.compare(t1.type, t2.type) );

8版之前的版本会使用匿名Comparator

执行相同的操作