简体   繁体   English

用Java最好的方法来对具有不同对象的另一个列表进行排序

[英]Java best way to sort a list by another list with different objects

Lets say I have a list with objects, lets call it listA which is unordered, and it has objects of type A . 可以说我有一个包含对象的列表,我们称其为无序的listA ,并且具有类型为A对象。 type A has a field called name . 类型A有一个名为name的字段。 now, I have another list, which is ordered. 现在,我还有另一个列表,已排序。 let's call it listB and it is ordered. 我们称它为listB ,它是有序的。 the objects in this list are of type B and they also had a field name . 此列表中的对象是B类型,并且它们也具有字段name

Now, I want listA to be ordered as listB , and the only thing that is the same in those two lists is the field name which is the same in both objects. 现在,我希望将listA排序为listB ,并且在这两个列表中唯一相同的是两个对象中相同的字段name

what is the most efficient way to do so? 最有效的方法是什么?

I hope I'm understanding your problem. 希望我能理解您的问题。

Is the field 'name' a common field shared by the two types of Object (A and B)? 字段“名称”是两个对象(A和B)共享的公共字段吗? In other words, do the two types (A and B) extend the same Class C that contains the field 'name'? 换句话说,两种类型(A和B)是否扩展了包含字段“名称”的同一类C? If so you could implement the Comparable in Class C and then Collections.sort() would do the trick for you. 如果是这样,您可以在C类中实现Comparable ,然后Collections.sort()将为您解决问题。 All you have to do, while implementing the comparable, would be to 'teach' it how to compare the field 'name' so that it orders, in the same manner, the list of type B objects, you specify, are ordered. 在实现可比对象的同时,您要做的就是“教”它如何比较“名称”字段,以便以相同的方式对您指定的B类对象列表进行排序。

Another way to do this , in case your classes don't have anything in common, therefore not making sense of having a superclass C, would be to create a Comparator interface, where you could specify the fields that can be used to compare two distinct objects and then do the sorting using those fields, in other words: 这样做的另一种方法是 ,如果您的类没有任何共同点,因此没有超类C的意义,那就是创建一个Comparator接口,您可以在其中指定可用于比较两个不同的字段的字段。对象,然后使用这些字段进行排序,换句话说:

  1. Create a Interface with the method getCompareFields() returns String[]; 使用方法getCompareFields()创建一个接口,返回String []; (for example) (例如)
  2. Implement interface of point 1. in objects A and B 在对象A和B中实现点1的接口
  3. Implement a sorting algorithm that uses this interface's getCompareFields() method for sorting. 实现使用此接口的getCompareFields()方法进行排序的排序算法。

And, another way even, for you to do this, but, in my opinion, would be more complicated, would be to use reflection to get the field 'name' of both objects, in case they are not related in any kind. 而且, 即使是另一种方式,您也可以这样做,但是在我看来,这将更加复杂,如果它们之间没有任何关联,则使用反射来获取两个对象的字段“名称”。

I hope this helps you. 我希望这可以帮助你。

EDIT Example of reflection: 编辑反射示例:

Class TypeA (Example) Class A类(示例)

public class TypeA {
private String name;
private String id;

public TypeA() {
    this(null, null);
}

public TypeA(String name, String id) {
    this.name = name;
    this.id = id;
}

public String getName() {
    return this.name;
}

public String getId() {
    return this.id;
}

@Override
public String toString() {
    return "(" + name + ", " + id + ")";
}

} }

Class TypeB (Example) Class TypeB(示例)

public class TypeB {
private String name;
private List<Integer> numbers;

public TypeB() {
    this(null);
}

public TypeB(String name, int ... numbers) {
    this.name = name;

    this.numbers = new LinkedList<Integer>();
    if (numbers != null) {
        for (int i : numbers) {
            this.numbers.add(i);
        }
    }
}

public String getName() {
    return this.name;
}

public List<Integer> getANumber() {
    return this.numbers;
}

@Override
public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("(").append(name).append(", [");

    Iterator<Integer> i = this.numbers.iterator();

    if (i.hasNext()) {
        builder.append(i.next());

        while (i.hasNext()) {
            builder.append(", ").append(i.next());
        }
    }

    builder.append("])");
    return builder.toString();
}

} }

Reflection Name Comparator: 反射名称比较器:

public class NameReflectionComparator implements Comparator<Object> {

@Override
public int compare(Object o1, Object o2) {
    if (o1 != null && o2 != null) {
        try {
            Method obj1_getNameMethod = o1.getClass().getMethod("getName");
            Method obj2_getNameMethod = o2.getClass().getMethod("getName");

            String obj1_name = (String) obj1_getNameMethod.invoke(o1);
            String obj2_name = (String) obj2_getNameMethod.invoke(o2);

            if (obj1_name != null) {
                return obj1_name.compareTo(obj2_name);
            } else if (obj2_name != null) {
                return obj2_name.compareTo(obj1_name);
            }
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }

    } else if (o1 != null && o2 == null) {
        return 1;
    } else if (o1 == null && o2 != null) {
        return -1;
    }

    return 0;
}

} }

Main: 主要:

public class Main {
public static void main(String[] args) {

    // both TypeA and TypeB have field name and method getName()
    // unsorted list
    List<TypeA> typeAList = new LinkedList<TypeA>();
    typeAList.add(new TypeA("Yves Larock", UUID.randomUUID().toString()));
    typeAList.add(new TypeA("I'm ok", UUID.randomUUID().toString()));
    typeAList.add(new TypeA("Aaah", UUID.randomUUID().toString()));
    typeAList.add(new TypeA("Noooh", UUID.randomUUID().toString()));

    // sorted list
    List<TypeB> typeBList = new LinkedList<TypeB>();
    typeBList.add(new TypeB("Aaah", 1, 2, 3));
    typeBList.add(new TypeB("I'm ok", 1));
    typeBList.add(new TypeB("Noooh", 34, 3));
    typeBList.add(new TypeB("Yves Larock", 4, 5, 3, 9));

    System.out.println("ListA:\n" + typeAList);
    System.out.println("ListB:\n" + typeBList);

    NameReflectionComparator comparator = new NameReflectionComparator();
    Collections.sort(typeAList, comparator);


    System.out.println("=== AFTER SORT ====\nListA:\n" + typeAList);
    System.out.println("ListB:\n" + typeBList);
}

} }

Result: 结果:

ListA: [(Yves Larock, f40cb523-58e8-4ee2-aa4f-991ce7e7cdd5), (I'm ok, 5a66b9d9-7a27-4529-ab64-c893291bd9b0), (Aaah, 4842fd55-47e5-48ac-b7b6-ebc7acf7023c), (Noooh, 8dc89675-bc28-4374-aff2-0c5d0ae6dd9d)] ListA:[(Yves Larock,f40cb523-58e8-4ee2-aa4f-991ce7e7cdd5),(我很好,5a66b9d9-7a27-4529-ab64-c893291bd9b0),(Aaah,4842fd55-47e5-48ac-b7b6-ebc7acf702 Noooh,8dc89675-bc28-4374-aff2-0c5d0ae6dd9d)]

ListB: [(Aaah, [1, 2, 3]), (I'm ok, 1 ), (Noooh, [34, 3]), (Yves Larock, [4, 5, 3, 9])] ListB:[(Aaah,[1,2,3]),(我很好, 1 ),(Noooh,[34,3]),(Yves Larock,[4,5,3,9])]

=== AFTER SORT ==== ListA: [(Aaah, 4842fd55-47e5-48ac-b7b6-ebc7acf7023c), (I'm ok, 5a66b9d9-7a27-4529-ab64-c893291bd9b0), (Noooh, 8dc89675-bc28-4374-aff2-0c5d0ae6dd9d), (Yves Larock, f40cb523-58e8-4ee2-aa4f-991ce7e7cdd5)] ===排序后==== ListA:[(Aaah,4842fd55-47e5-48ac-b7b6-ebc7acf7023c),(我可以,5a66b9d9-7a27-4529-ab64-c893291bd9b0),(Noooh,8dc89675-bc28- 4374-aff2-0c5d0ae6dd9d),(Yves Larock,f40cb523-58e8-4ee2-aa4f-991ce7e7cdd5)]

ListB: [(Aaah, [1, 2, 3]), (I'm ok, 1 ), (Noooh, [34, 3]), (Yves Larock, [4, 5, 3, 9])] ListB:[(Aaah,[1,2,3]),(我很好, 1 ),(Noooh,[34,3]),(Yves Larock,[4,5,3,9])]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM