根据另一个列表的顺序排序列表

时间:2012-09-01 13:05:56

标签: java list map arraylist

我有两个列表,其中一个列表的顺序与其他列表的顺序不同,在列表中我添加了一个映射,其中两个列表中的键顺序不同。我希望列表的顺序相同。我怎么能这样做?

Map<Long, String> attfieldMap = null;
attfieldMap = view.getNameMap(form);

List<Field> auditMap = new ArrayList<Field>();
if (itemId != 0) {

    Item dom = getRecord();

    Map<FormField, Object> tempValues = dom.getValues();
    List<Field> oldValues = new ArrayList<Field>();

    for (Map.Entry<FormField, Object> values : tempValues
            .entrySet()) {
        Field oldFld = new Field();
        Form form = (Form) values.getKey();

        if (attfieldMap.get(form.getField().getId()) != null) {
            oldFld.setKey(attfieldMap.get(form.getField()
                    .getId()));
            oldFld.setValue(values.getValue());

            oldValues.add(oldFld);
        }
    }
}


for (Map.Entry<Long, String> attfieldEntry : attfieldMap.entrySet()) {
    // Mandates to declare within loop
    Field attributeFld = new Field;

    attributeFld.setKey(attfieldEntry.getValue());
    attributeFld.setValue(String.valueOf(attfieldEntry.getKey()));

    auditMap.add(attributeFld);
}

列表auditMap包含带有密钥att13att12att14oldValues的地图,其中包含带有密钥att12的地图,{{1 },att13。我需要此列表与att14列表的顺序相同。如何订购?

根据回答编辑下面的代码:这里数据被复制,只是排序,即使列表大小不同。列表1应该有自己的数据,list2应该有相同的数据,但是应该保持顺序

auditMap

这是我的实际代码,数据没有得到排序.auditMap中的键是1,2,3,4,旧值是1,3,2旧值的结果应该是1,2,3但它没有发生

2 个答案:

答案 0 :(得分:3)

如果您想要的是,那么在该代码片段的末尾,auditMap和oldValues应该是相同的顺序,只需通过Collections.sort()方法运行它们,并为Field对象提供适当的比较器。

如果没有,则在IF块之后创建auditMapArray,一个大小与oldValues一样的字段数组(你当然需要在IF块之外声明)。每次你想在auditMap中插入一个元素时,在oldValues中找到它的索引(假设你有正确的equals方法实现来检查两个Field对象是否相等)并插入auditMapArray中的相同位置,最后得到auditMap列表使用Arrays.asList(auditMapArray)

您的代码段的修改版本,可确保auditMap中存在的oldValues中的所有值的顺序相同。审计地图中的任何其他元素都会附加在最后。

Map<Long, String> attfieldMap = null;
attfieldMap = view.getNameMap(form);

List<Field> oldValues = new ArrayList<Field>();
if (itemId != 0) {

    Item dom = getRecord();

    Map<FormField, Object> tempValues = dom.getValues();

    for (Map.Entry<FormField, Object> values : tempValues
            .entrySet()) {
        Field oldFld = new Field();
        Form form = (Form) values.getKey();

        if (attfieldMap.get(form.getField().getId()) != null) {
            oldFld.setKey(attfieldMap.get(form.getField()
                    .getId()));
            oldFld.setValue(values.getValue());

            oldValues.add(oldFld);
        }
    }
}

List<Field> otherFields = new ArrayList<Field>();
Field [] auditMapArray = new Field[oldValue.size()];
int index;
for (Map.Entry<Long, String> attfieldEntry : attfieldMap.entrySet()) {
    // Mandates to declare within loop
    Field attributeFld = new Field;

    attributeFld.setKey(attfieldEntry.getValue());
    attributeFld.setValue(String.valueOf(attfieldEntry.getKey()));

    index = oldValues.indexOf(attributeFld);
    if (index > 0) {
        auditMapArray[index] = attributeFld;
    }
    else
    {
        System.err.println(attributeFld + " not found in oldValues");
        otherFields.add(attributeFld);
    }
}

List<Field> auditMap = Arrays.asList(auditMapArray);
auditMap.addAll(otherFields);

答案 1 :(得分:3)

您可以使用自定义比较器对第二个列表进行排序,使用第一个列表中的项目索引作为键。像这样:

Collections.sort(list2, new Comparator() {
    public int compare(Object o1, Object o2) {
        return list1.indexOf(o1) - list1.indexOf(o2);
     }});

更新:如果列表未排序,indexOf可能需要一些时间,并且由于此方法经常被称为非常,因此最好先存储对象的索引在Map中,即创建HashMap {item:list1.indexOf(item)}并在compare方法中使用此地图。

将它们放在一起,并使用示例中的名称:

final Map<Field, Integer> indices = new HashMap<Field, Integer>();
for (int i=0; i < oldValues.size(); i++) {
    indices.put(oldValues.get(i), i);
}
Collections.sort(auditMap, new Comparator<Field>() {
    public int compare(Field o1, Field o2) {
        int index1 = indices.containsKey(o1) ? indices.get(o1) : -1;
        int index2 = indices.containsKey(o2) ? indices.get(o2) : -1;
        return index1 - index2;
     }});