Как назначить инкрементное значение в список в Java 8 - PullRequest
0 голосов
/ 04 июня 2018

Вы предполагаете, что существует список объектов.Список отсортирован по одному или нескольким полям этого объекта.Итак, согласно отсортированному списку, я хочу установить поле этого объекта с инкрементным значением.Для пояснения обратите внимание на приведенный ниже пример:

public class ObjectTest {
   int id;
   int userId;
   int code;
}

Как и в случае с ObjectTest, любой пользователь имеет свой собственный код.Есть список ObjectTest.

List<ObjectTest> objTests;

Он отсортирован:

objTests.sort(Comparator.comparing(DataSet::getUserId).thenComparing(DataSet::getCode));

Так что после сортировки по ИД и коду я хочу установить значение от 1 до того, где любой пользователь имеетсвой собственный код.При изменении userId инкрементное значение снова сбрасывается в 1.

Если существует следующая коллекция ObjectTest.

    id     userId    code
--------------------------------
             100     5
             200     6
             100     7
             200     9
             200     10
             100     2

После описанного выше сценария следующая коллекция будет:

id      userId     code
1        100        2
2        100        5
3        100        7
1        200        6
2        200        9
3        200        10

Возможно ли это с лямбда-выражением в java

Ответы [ 4 ]

0 голосов
/ 04 июня 2018

Я согласен с @Varvarigos Emmanouil, иногда без Stream API обойтись проще.

Collections.sort(list, Comparator.comparing(ObjectTest::getUserId).thenComparing(ObjectTest::getCode));
int userId = list.get(0).userId;
int index = 0;
for (ObjectTest objectTest:list){
     if (userId != objectTest.userId){
          index = 0;
          userId = objectTest.userId;
     }
      objectTest.setId(++index);
}
0 голосов
/ 04 июня 2018

Вы можете создать карту userId для целочисленного атомарного целевого объекта, а затем выполнить итерацию по отсортированному списку для установки идентификатора.

Map<Integer, AtomicInteger> userIds = 
        objTests.stream()
        .map(obj -> Integer.valueOf(obj.getUserId()))
        .distinct()
        .collect(Collectors.toMap(Function.identity(), 
                 (id) -> new AtomicInteger(1)));

Приведенная выше карта содержит целочисленный атомный объект для каждого уникальногоuserId.

objTests.stream()
        .forEach(obj -> obj.setId(userIds.get(obj.getUserId())
                                   .getAndIncrement()));

Этот последний код просто перебирает отсортированный список, а затем назначает чтение id из атомарного целого числа, связанного с идентификатором пользователя в экземпляре.

0 голосов
/ 04 июня 2018

Что-то вроде этого должно работать:

List<ObjectTest> resultSet = 
objTests.stream()
        .sorted(Comparator.comparing(ObjectTest::getUserId).thenComparing(ObjectTest::getCode))
        .collect(Collectors.groupingBy(ObjectTest::getUserId, LinkedHashMap::new, Collectors.toList()))
        .values()
        .stream()
        .map(e -> {
            IntStream.range(0, e.size())
                    .forEach(i -> e.get(i).setId(i + 1));
            return e;
        })
        .flatMap(Collection::stream)
        .collect(Collectors.toList());

Обратите внимание, я не скомпилировал этот код.

0 голосов
/ 04 июня 2018

Это может быть возможно, но вы, скорее всего, не должны решать его с помощью streams API .

Причина в том, что streams API представляет собой реализацию Javas функциональное программирование и одним из ключевых предположений в FP является то, что объекты (или, лучше, любые данные) не имеют никакого отношения друг к другу и ни одна функция не изменяетсостояние входных данных .

Поэтому ваше требование противоречит ключевому допущению FPs.

Какая ваша идея, чтобы получить мою цель?- reza ramezani matin

Группировать объекты по идентификатору пользователя:

Map<Integer,ObjectTest> userIdMap= objTests.stream()
    .collect(Collectors.groupingBy(
                           ot ->ot.userId , ot ->ot
                    ));

перечислять с устаревшими циклами:

for(Collection<ObjectTest> ol : userIdMap.values()){
   objectList = new ArrayList(ol);
   Colections.sort(ol, /* comparator here*/);
   for(int id = 0; id < ol.size();)
      objectList.get(id).id=++id;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...