简体   繁体   中英

Java, Sorting lists different type by date

I have three lists List<A> a; , List<B> b; and List<C> c; . The types A,B and C have date attributes. How i can order the three list by date and print all of the items by date, Like this example

        List<A> a = new ArrayList<A>();
        a.add(new A("1", "22/04/2017", "", ""));
        a.add(new A("2", "25/04/2017", "", ""));
        a.add(new A("3", "30/04/2017", "", ""));
        a.add(new A("4", "01/04/2017", "", ""));


        List<B> b = new ArrayList<B>();
        b.add(new B("5", "23/04/2017", "", ""));
        b.add(new B("6", "05/04/2017", "", ""));

        List<C> c = new ArrayList<C>();
        c.add(new C("7", "26/04/2017", "", ""));
        c.add(new C("8", "02/04/2017", "", ""));

output is:

        4   01/04/2017  --> A
        8   02/04/2017  --> C
        6   05/04/2017  --> B
        1   22/04/2017  --> A
        5   23/04/2017  --> B
        2   25/04/2017  --> A
        7   26/04/2017  --> C
        3   30/04/2017  --> A

If you are using Java 8

If i can understand your Class design look like this :

Class A

class A {

    String s1;
    String s2;
    String s3;
    String s4;

    public A(String s1, String s2, String s3, String s4) {
        this.s1 = s1;
        this.s2 = s2;
        this.s3 = s3;
        this.s4 = s4;
    }
    //..getters and setter
}

Class B

class B extends A {

    public B(String s1, String s2, String s3, String s4) {
        super(s1, s2, s3, s4);
    }

}

Class C

class C extends A {

    public C(String s1, String s2, String s3, String s4) {
        super(s1, s2, s3, s4);
    }
}

In this case you can use :

//Create a List, and add all the a, b, c List to this list
List<A> k = new ArrayList<>();
k.addAll(a);
k.addAll(b);
k.addAll(c);

then you can sort this List using a Comparator like this

Collections.sort(k, new Comparator<A>() {
    public int compare(A p1, A p2) {
        return p1.getS2().compareTo(p2.getS2());
    }
});

Print your List

k.forEach((v) -> System.out.println(v.getS2()));

EDIT

Solution 2

In case there are no relation between your Class then you can use :

List<String> k = new ArrayList<>();
a.forEach((v)-> k.add(v.s2));
b.forEach((v)-> k.add(v.s2));
c.forEach((v)-> k.add(v.s2));

Collections.sort(k, String::compareTo);

k.forEach((v) -> System.out.println(v));

Solution 3

If you want to go far, you can :

  1. Create a common class (CommonClass) which take the common attributes between the Three classes
  2. Create a List of this type (CommonClass)
  3. Loop throw this 3 Lists and create new Objects of CommonClass and add them to the new List
  4. Then Sort this final List

Or :

Solution 4

You can create a List<List<String>> like this :

List<List<String>> k = new ArrayList<>();
a.forEach((v) -> k.add(Arrays.asList(v.s1, v.s2, v.s3, v.s4)));
b.forEach((v) -> k.add(Arrays.asList(v.s1, v.s2, v.s3, v.s4)));
b.forEach((v) -> k.add(Arrays.asList(v.s1, v.s2, v.s3, v.s4)));


Collections.sort(k, (o1, o2) -> {
    return o1.get(1).compareTo(o2.get(1));
});

k.forEach((v) -> System.out.println(v.get(0) + "____" + v.get(1)));

You could create a stream of all the items and sort it using a custom comparator:

Stream.of(a, b, c).flatMap(List::stream)
        .sorted(Comparator.comparing(o -> {
            if (o instanceof A) return ((A) o).date;
            if (o instanceof B) return ((B) o).date;
            if (o instanceof C) return ((C) o).date;
            throw new RuntimeException("illegal type");
        }))
        .forEach(System.out::println);

When you say that you want to order three lists of different types you are really saying that you want to create a single collection and sort it. That means (for Java at least) that the items need to have a common type.

Once they are in a common collection there needs to be a common set of things you can do to the items. In the example you've given in the question the only thing they can do is be converted to a string, though I expect you'll eventually need to be able to do other things to them.

So I suggest you create an interface that contains the methods you want to perform on the sorted list and then add objects of that type into the list:

public interface ABC {
    Date getDate();
}

List<ABC> abcList;

Adding an A to that list would look like this:

abcList.add(a::getDate);

Similarly for B and C .

Now sorting and printing the list is pretty trivial:

abcList.stream()
    .sorted(Comparator.comparing(ABC::getDate))
    .map(ABC::toString)
    .forEach(System.out::println);

If your classes aren't related at all there is no other way than to assemble first all A, B and C into one of type Object:

List<Object>

Then sort it providing a Comparator which extracts all the needed values the hard way (using if..else cascades with instanceof).

If at least the getter methods of the different classes would have the same name (eg getId() for the first string, getDate() for the second string, etc.) you can avoid the instanceof if..else by using introspection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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