Есть ли способ разбить список объектов на n списков в зависимости от количества уникальных значений поля объекта? - PullRequest
0 голосов
/ 02 августа 2020

У меня есть метод, который возвращает список объектов.

В этом объекте есть поле OrderType String.

Есть ли способ разделить этот список на n чисел списков в зависимости от уникальных значений orderType?

Например, метод возвращает список, содержащий 10 объектов, тогда 4 из них имеют значение orderType, равное x, 3 - значение orderType, равное y, затем еще 4 - значение of z.

, то результатом будет 3 списка, содержащих 4,3,4 объекта соответственно

orderType не только имеет x, y и z как возможные значения.

Мне сложно поместить это в настоящий код, но моя идея такая

List<Orders> orderList = getOrder();


for(int i=0; i<orderList.size();i++){

   if(orderList.get(i).orderType is unique){
        create a new list
   }else{
        add to an existing list having the same orderType
   }
}

Ответы [ 2 ]

1 голос
/ 02 августа 2020

Я бы предложил эту довольно общую функцию:

    public static <T, U> Map<U, List<T>> getLists(List<T> values, Function<T, U> orderBy) {
        Map<U, List<T>> lists = new HashMap<>();
        for (T value : values) {
            U type = orderBy.apply(value);
            if (!lists.containsKey(type)) {
                lists.put(type, new ArrayList<>());
            }
            lists.get(type).add(value);
        }
        return lists;
    }

Класс заказа:

class Order {

        private String orderType;
        private String name;

        public Order(String orderType, String name) {
            this.orderType = orderType;
            this.name = name;
        }

        public String getOrderType() {
            return orderType;
        }

        public String getName() {
            return name;
        }

    }

Как использовать:

    public static void main(String args[]){
        List<Order> orders = new ArrayList<>();
        orders.add(new Order("TYPE1", "Order1"));
        orders.add(new Order("TYPE2", "Order2"));
        orders.add(new Order("TYPE1", "Order3"));
        orders.add(new Order("TYPE1", "Order4"));
        orders.add(new Order("TYPE2", "Order5"));
        orders.add(new Order("TYPE1", "Order6"));
        orders.add(new Order("TYPE1", "Order7"));
        orders.add(new Order("TYPE1", "Order8"));

        Map<String, List<Order>> map =  getLists(orders, Order::getOrderType);

        for (String key : map.keySet()) {
            System.out.println(key);
            for (Order order : map.get(key)) {
                System.out.println(order.getOrderType() + " " + order.getName());
            }
            System.out.println();
        }
    }
0 голосов
/ 02 августа 2020

Я думаю, что проще вытащить элемент на карту, тогда вы можете воспользоваться третьим параметром Collectors.toMap, который объединяет значения одного и того же ключа.

public void tryIt() {
    // given
    class Foo {
        String x;

        Foo(String x) {
            this.x = x;
        }

        @Override
        public String toString() {
            return this.x;
        }
    }
    List<Foo> foos = new ArrayList<>();
    IntStream.range(0, 4).forEach(i -> {
        foos.add(new Foo("x"));
        foos.add(new Foo("z"));
    });
    IntStream.range(0, 3).forEach(i -> foos.add(new Foo("y")));

    // create a mapping of element, to list of original object, grouping by same element key
    Map<String, List<Foo>> collect = foos.stream().collect(Collectors.toMap(
            f -> f.x, 
            Collections::singletonList,
            (l1, l2) -> Stream.concat(l1.stream(), l2.stream()).collect(Collectors.toList())));

    System.out.println(collect);
}

Вывод

{x=[x, x, x, x], y=[y, y, y], z=[z, z, z, z]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...