3

我创建了一个 Vector 对象来将对象中的数据存储TableVector<Table>. Vector<Table>包含如下组件。

[Vector<Record> records, String tableName, String keyColumnName, int recordCount, int columnCount]

我需要按照tableName我自己的顺序在上面的 Vector 中排序并返回Vector<Table>sorted tableNames用于其他进程。

我写了如下方法。

private Vector<Table> orderTables(Vector<Table> loadTables) {

    List<String> tableNames = new ArrayList<String>();

    for (Table table : loadTables) {

        String tblName = table.getTableName();
        tableNames.add(tblName);

    }
    Collections.sort(tableNames, new MyComparable());

    return null;
}

但我不知道如何写Comparator这个。我自己的排序顺序存储在.properties文件中。我可以阅读并获得价值。但我不知道如何比较它。

我怎么能做到?

4

3 回答 3

5

澄清前

您需要为委托给比较器ComparatorTable对象编写一个tableName

new Comparator<Table>() {
    @Override public int compare(Table one, Table two) {
        return one.getTableName().compareTo(two.getTableName());
    }
}

请注意,这将认为Table具有相同名称的 s 是相等的。HashMap如果您将这些表放在 a或中,这可能会搞砸HashSet。为避免这种情况,您可以检测这种情况并one.hashCode() - two.hashCode()在表名相同时返回。

GuavaComparisonChain是编写此类多阶段比较的便捷方式:

new Comparator<Table>() {
    @Override public int compare(Table one, Table two) {
        return ComparisonChain.start()
                 .compare(one.getTableName(), two.getTableName())
                 .compare(one.hashCode(), two.hashCode())
                 .result();
    }
}

澄清后

好的,问题是强加一个预定义的排序顺序,而不是Table按名称对 s 进行排序。在这种情况下,您需要Comparator知道.properties文件中定义的顺序。

实现此目的的一种方法是初始化表名到排序顺序索引的映射,并在比较期间引用该映射。给定属性值:

SORT_ORDER = SALES,SALE_PRODUCTS,EXPENSES,EXPENSES_ITEMS

映射应如下所示:

{
    SALES: 0,
    SALE_PRODUCTS: 1,
    EXPENSES: 2,
    EXPENSES_ITEMS: 3
}

这是比较器的样子:

private static class PredefinedOrderComparator implements Comparator<Table> {

    public PredefinedOrderComparator() {

        // Initialize orderIndex here

    }

    private final Map<String, Integer> orderIndex;

    @Override public int compare(Table one, Table two) {
        return orderIndex.get(one.getTableName()) - orderIndex.get(two.getTableName());
    } 

}

要从属性值填充orderIndex,您需要:

  1. getProperty()使用您提到的获取逗号分隔的列表
  2. 用逗号分割该值(我建议使用Guava'sSplitter,但String.split或者其他人也可以)
  3. 初始化一个新HashMap<String, Integer>的和一个int index = 0
  4. 遍历拆分标记,将当前标记映射到index并递增index

请注意隐含的假设,即所有表名中都没有逗号。

于 2012-05-09T09:29:35.310 回答
1
 public class MyComparable implements Comparator<Table>{
   @Override
   public int compare(Table table1, Table table2) {
    return (table1.getTableName().compareTo(table2.getTableName());
   }
 }

确保您已经覆盖了 Table 类中的 hashcode 和 equals 来实现这一点。

于 2012-05-09T09:29:05.663 回答
1

我给你写了一个关于如何使用比较器的非常简单的例子。如果你创建一个名为 Main 的类,将下面的内容复制粘贴到其中,编译并运行它,你可以看到发生了什么。

比较器只需要实现一个接口。为此,它需要实现一种方法(public int compare(T arg0, T arg1)。您可以在其中指定集合将如何排序;在这种情况下,根据 alfabet。

我希望这可以帮助你。

import java.util.*;

public class Main {

    public static void main(String[] args) {
        System.out.println("Start\n");
        List<Item> items = new ArrayList<Item>();
        for(String s : new String[]{"mzeaez", "xcxv", "hjkhk", "azasq", "iopiop"}) {
            items.add(createItem(s));
        }
        System.out.println("Items before sort:");
        System.out.println(Item.toString(items));
        Collections.sort(items, new ItemComparator());
        System.out.println("Items after sort:");
        System.out.println(Item.toString(items));
        System.out.println("End");
    }

    private static Item createItem(String s) {
        Item item = new Item();
        item.setS(s);
        return item;
    }

}

class Item {

    private String s;

    public String getS() {
        return s;
    }

    public void setS(String s) {
        this.s = s;
    }

    @Override
    public String toString() {
        return "Item: " + s;
    }

    public static String toString(Collection<Item> items) {
        String s = "";
        for(Item item : items) {
            s += item + "\n";
        }
        return s;
    }    

}

class ItemComparator implements Comparator<Item> {

    @Override
    public int compare(Item item1, Item item2) {
        return item1.getS().compareTo(item2.getS());
    }

}
于 2012-05-09T09:47:10.813 回答