Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在字段上使用基于规则的计算器对Java对象列表进行排序?_Java_Sorting - Fatal编程技术网

如何在字段上使用基于规则的计算器对Java对象列表进行排序?

如何在字段上使用基于规则的计算器对Java对象列表进行排序?,java,sorting,Java,Sorting,我想使用给定的值对特定字段上对象的ArrayList进行排序 例如,我们有一个对象的列表: public Thing { public String name; public String type; } List<Thing> things = new ArrayList<Thing>(); RuleBasedCollator ruleBasedCollator = new RuleBasedCollator("< Table < Plate &

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

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

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

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

RuleBasedCollator ruleBasedCollator = new RuleBasedCollator("< Table < Plate < Fork < Knife");
公共事物{
公共字符串名称;
公共字符串类型;
}
List things=new ArrayList();
RuleBasedCalator RuleBasedCalator=新的RuleBasedCalator(“
现在,在创建了
Thing
对象并将它们添加到
things
列表之后,我想对该列表进行排序,获取
类型的第一件事物
“table”和类型的最后一件事物“knife”


有人知道怎么做吗?

据我所知,
RuleBaseCollator
用于排序
String
s,至少我在Collator类中是这样说的,它是超类。我会使用一个比较器,类似这样:

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);
}
public class ThingSorter{
公共枚举类型{
//需要排序顺序,按顺序排序:
//桌<盘<叉<刀
桌子、盘子、叉子、刀
}
公共静态类事物{
私有字符串名称;
私人物品类型;
公共事物(字符串名称,ThingType tt){
this.name=名称;
类型=tt;
}
公共字符串toString(){
返回名称+“[”+类型+“]”;
}
}
公共静态类MyThingComparator实现Comparator{
@凌驾
公共整数比较(t1事物,t2事物){
返回t1.type.ordinal()-t2.type.ordinal();
}
}
公共静态类MyReverseThingComparator实现Comparator{
@凌驾
公共整数比较(t1事物,t2事物){
返回t2.type.ordinal()-t1.type.ordinal();
}
}
公共静态void main(字符串[]args)引发异常{
List things=new ArrayList();
事物。添加(新事物(“一”,事物类型。刀));
添加(新事物(“两个”,ThingType.FORK));
添加(新事物(“三”,ThingType.PLATE));
添加(新事物(“四”,ThingType.TABLE));
System.out.println(“未排序:\n”+事物);
Collections.sort(things,newmythingcomparable());
System.out.println(“排序:\n”+事物);
Collections.sort(things,newMyReverseThingComparable());
System.out.println(“排序:\n”+事物);
}
}


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

我终于找到了使用树映射的解决方案。我对键使用“type”属性,对值使用事物列表。我没有使用RuleBasedCalator,而是创建了一个ListBasedCalator扩展Collator,因为RuleBasedCalator规则用于字符,而不用于单词

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;
}
公共类ListBasedCollector扩展了Collator{
私人名单;
公共ListBasedCollector(字符串[]数组){
列表=数组。asList(数组);
}
@凌驾
公共整数比较(字符串源、字符串目标){
如果(!list.contains(目标)){
返回1;
}
如果(!list.contains(源)){
返回-1;
}
返回Integer.valueOf(list.indexOf(source)).compareTo(Integer.valueOf(list.indexOf(target)));
}
@凌驾
公共排序规则键getCollationKey(字符串源){
返回null;
}
@凌驾
公共int hashCode(){
返回0;
}
}

下面是我如何构建树映射的:

String[] sortingList = {"TABLE", "PLATE", "FORK", "KNIFE"};
ListBasedCollator listBasedCollator = new ListBasedCollator(sortingList);
Map<String, List<Thing>> thingMap = new TreeMap<String, List<Thing>>(listBasedCollator);
String[]排序列表={“表”、“板”、“叉”、“刀”};
ListBasedCalator ListBasedCalator=新的ListBasedCalator(排序列表);
Map thingMap=新树映射(ListBasedCollector);
因此,thingMap将始终使用ListBasedCalator按类型排序。
我还可以按字母顺序对每种不同类型的列表进行排序。

您当然可以按照前面的答案使用
TreeMap
enum
;一个更简单的替代方法是只使用自定义的兼容程序,而不使用
enum
。如果您使用的是Java 8,您可以将其简化为一行:

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

pre-8版本将对匿名的
比较器执行相同的操作,您可以尝试类似的操作,而不是在比较器的compare方法中使用compareTo,您可以调用RuleBasedCalator的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;
    }
});

非常感谢这个似乎运行良好的解决方案。但是,您可以将我的“type”属性转换为预定义的枚举,在我的例子中,将其保留为字符串很重要。我终于用TreeMap找到了另一个解决方案。非常感谢,我不知道这个新的Java8语法听起来很好。@Raedwald From
java.text