0

There is a list with several elements. The elements in it has two criteria: id and value. I want to sort them by value and get first three elements, then put the elements which id != 1 to the end of the list.

for example:

class Test {
    int id;
    int value;

    public Test(int id, int value) {
        this.id = id;
        this.value = value;
    }
}
Test a = new Test(1,4);
Test b = new Test(2,3);
Test c = new Test(1,1);
Test d = new Test(2,5);
origin list: a,b,c,d

sort by value and get first three elements: c,b,a

put the elements which id != 1 to the end of the list: c,a,b

how to implement it in a efficient and elegant way?

vszholobov
  • 2,133
  • 1
  • 8
  • 23
cmfu
  • 19
  • 2
  • 2
    Use a [`Comparator`](https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html) as a starting point – MadProgrammer Aug 18 '21 at 03:37
  • 1
    Maybe something like [this](https://stackoverflow.com/questions/4258700/collections-sort-with-multiple-fields/20093589) or [this](https://stackoverflow.com/questions/4805606/how-to-sort-by-two-fields-in-java/26865122) or just [this](https://www.google.com/search?client=safari&rls=en&q=java+sort+collection+by+multiple+fields&ie=UTF-8&oe=UTF-8) might help – MadProgrammer Aug 18 '21 at 03:38
  • Very similar questions have been asked and answered before. Please search. – Ole V.V. Aug 18 '21 at 04:44

1 Answers1

2

You can solve this in one line, using stream. You would need sorted to sort elements and limit to take first three elements. First sort by value, then take first three elements, then sort by id to move element with id != 1 to the end and store result in some collection.

class Test {
    int id;
    int value;

    public Test(int id, int value) {
        this.id = id;
        this.value = value;
    }

    @Override
    public String toString() {
        return "Test{" +
                "id=" + id +
                ", value=" + value +
                '}';
    }

    public static void main(String[] args) {
        Test a=new Test(1,4);
        Test b=new Test(2,3);
        Test c=new Test(1,1);
        Test d=new Test(2,5);

        List<Test> result = Stream.of(a, b, c, d)
                .sorted(Comparator.comparingInt(x -> x.value))
                .limit(3)
                .sorted((x, y) -> {
                    if(x.id == 1 && y.id != 1) {
                        return -1;
                    }

                    if(y.id == 1 && x.id != 1) {
                        return 1;
                    }

                    return 0;
                })
                .collect(Collectors.toList());

        System.out.println(result);
    }
}

Output

[Test{id=1, value=1}, Test{id=1, value=4}, Test{id=2, value=3}]
vszholobov
  • 2,133
  • 1
  • 8
  • 23