Merge two lists in Java and sort them using Object property and another condition I have two lists List&lt;Person&gt; list1 = new ArrayList(), list2 = new ArrayList(); (Not the same size), of the class Person:

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" + "name=" + name + ", age=" + age + '}';
    }

}


I want to create a new list using list1 and list2 sorted by age (descending), but I also another condition that is better explained with an example: 

//L1 = from list1, L2 = from list2
//looping trough the new list
Person{name=Alec L1, age=75}
Person{name=Menard L1, age=50} //Bob should be here
Person{name=Bob L2, age=50}


He should, because his age is equal to Menard, Alec is from L1 and two Person from L1 can't be one after another is this kind of situation happens.

A complete list should look like this:

Person{name=Giant L2, age=100}
Person{name=Derp L1, age=50}
Person{name=John L2, age=50}
Person{name=Menard L1, age=44}
Person{name=Lili L2, age=44}
Person{name=Lili L1, age=44}
Person{name=Menard L2, age=44}
Person{name=Bob L1, age=22}
Person{name=Alec L2, age=21}
Person{name=Alec L1, age=21}
Person{name=Herp L2, age=21}
Person{name=Herp L1, age=21}
Person{name=Alice L1, age=12}
Person{name=Little L2, age=5}


Here is my complete code to achieve this result:

    List&lt;Person&gt; list1 = new ArrayList(), list2 = new ArrayList();

    list1.add(new Person("Derp L1", 50));
    list1.add(new Person("Alec L1", 21));
    list1.add(new Person("Herp L1", 21));
    list1.add(new Person("Menard L1", 44));
    list1.add(new Person("Lili L1", 44));
    list1.add(new Person("Alice L1", 12));
    list1.add(new Person("Bob L1", 22));

    Collections.sort(list1, new Comparator&lt;Person&gt;() {
        @Override
        public int compare(final Person object1, final Person object2) {
            return object2.getAge()-object1.getAge();
        }
    });


    list2.add(new Person("Little L2", 5));
    list2.add(new Person("Lili L2", 44));
    list2.add(new Person("Alec L2", 21));
    list2.add(new Person("Herp L2", 21));
    list2.add(new Person("Menard L2", 44));
    list2.add(new Person("Giant L2", 100));
    list2.add(new Person("John L2", 50));


    Collections.sort(list2, new Comparator&lt;Person&gt;() {
        @Override
        public int compare(final Person object1, final Person object2) {
            return object2.getAge()-object1.getAge();
        }
    });
    List&lt;Person&gt; allList = new ArrayList();
    int l1 = 0, l2 = 0;
    for (int i = 0; i &lt; list1.size()+list2.size(); i++)
        if (l1 &lt; list1.size() &amp;&amp; l2 &lt; list2.size())
            if (list1.get(l1).getAge() &gt; list2.get(l2).getAge())
                allList.add(list1.get(l1++));
            else if (list1.get(l1).getAge() &lt; list2.get(l2).getAge())
                allList.add(list2.get(l2++));
            else if (allList.size() &gt; 0)
            {
                if (list1.get(l1).getName().contains("L1") == allList.get(allList.size()-1).getName().contains("L1"))
                    allList.add(list2.get(l2++));
                else
                    allList.add(list1.get(l1++));
            }
            else
                allList.add(list1.get(l1++));
        else if (list1.size() == l1)
            allList.add(list2.get(l2++));
        else
            allList.add(list1.get(l1++));

    for (Person person : allList)
        System.out.println(person.toString());


But, is there another way to do it? More elegant code or using some built in Java class?
Your problem statement is not very clear.  As I understand it, you want to have a combined sorted list but interleave elements from list1 and list2 whenever the age is the same.

Here's a simple implementation of that logic.  I used java 8 streams to sort lists and put them in ArrayDeques.

import static java.util.stream.Collectors.toCollection;
import static java.util.Comparator.comparingInt;

static&lt;T&gt; List&lt;T&gt; interleaveSort(List&lt;T&gt; list1, List&lt;T&gt; list2, Comparator&lt;T&gt; cmp) {
    // sort the lists and set them up as queues
    Deque&lt;T&gt; x = list1.stream().sorted(cmp).collect(toCollection(ArrayDeque::new));
    Deque&lt;T&gt; y = list2.stream().sorted(cmp).collect(toCollection(ArrayDeque::new));

    List&lt;T&gt; result = new ArrayList&lt;&gt;(x.size() + y.size());

    while (!x.isEmpty() &amp;&amp; !y.isEmpty()) {
        if (cmp.compare(x.peek(), y.peek()) &gt; 0) {
            result.add(y.poll());
        } else {
            // whenever we pick from X, swap queues so next time we will favor the other list
            result.add(x.poll());
            Deque&lt;T&gt; t = x;
            x = y;
            y = t;
        }
    }
    // since the while loop terminates when one of the queues is empty
    // we should add the left-over elements
    result.addAll(x);
    result.addAll(y);

    return result;
}


Then, in your main method:

List&lt;Person&gt; allList=interleaveSort(list1, list2, comparing(Person::getAge).reversed());