Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort Java Stream like switch conditional

I'm trying to sort a stream by an specific order by one of its fields.

Now I'm achieving this by converting streams to list and using a switch and then rejoining them into a list in the desired order.


    fruits.forEach(fruit -> {
                switch (fruit.getName()) {
                    case "Orange":
                        orangesList.add(fruit);
                        break;
                    case "Apple":
                        applesList.add(fruit);
                        break;
                    case "WaterMelon":
                        watermelonList.add(fruit);
                        break;
                    default:
                        otherFruits.add(fruit);
                        break;
                }
    });

    genericFruitList.addAll(0, orangeList);
    genericFruitList.addAll(1, applesList);
    genericFruitList.addAll(2, watermelonList);
    genericFruitList.addAll(3, otherFruits);

I wonder if there's any change to achieve this using stream sorted method and using a custom comparator or something like that.

Thanks in advance.

like image 949
Antonio682 Avatar asked Dec 18 '22 04:12

Antonio682


1 Answers

You can create a comparator using an explicit order like

List<String> order = Arrays.asList("Orange", "Apple", "WaterMelon");
Comparator<String> comp
    = Comparator.comparingInt(name -> order.indexOf(name)-Integer.MIN_VALUE);

which can be used like

List<Fruit> genericFruitList = fruits
    .sorted(Comparator.comparing(fruit -> fruit.getName(), comp))
    .collect(Collectors.toList());

however, sorting the entire list, especially with an List.indexOf based comparator, can be quiet inefficient. An alternative would be

List<Fruit> genericFruitList = fruits
    .collect(Collectors.groupingBy(fruit -> fruit.getName()))
    .entrySet().stream()
    .sorted(Map.Entry.comparingByKey(comp))
    .flatMap(e -> e.getValue().stream())
    .collect(Collectors.toList());

which just performs a hash lookup per Fruit and only sort the distinct mappings.

This can be seen as a variant of Bucket Sort.

like image 189
Holger Avatar answered Dec 20 '22 19:12

Holger