Преобразование цикла arraylist с java 8 foreach - PullRequest
0 голосов
/ 01 февраля 2019

Необходимо преобразовать цикл (Java 6) в foreach (Java 8)

 List<CustomFormAttributeLite> custFormAttrLiteList = ArrayList ... ;
Map<String,Map<Long,Long>> customNameId = new HashMap<String, Map<Long,Long>>();
Map<Long,Long> custNameAndType = null;

for(CustomFormAttributeLite customFormAttributeLite:custFormAttrLiteList) {

    custNameAndType = new HashMap<Long,Long>();
    custNameAndType.put(customFormAttributeLite.getId(), customFormAttributeLite.getFieldType());

    customNameId.put(customFormAttributeLite.getName(), custNameAndType);
}

Я пытаюсь что-то подобное .. Но не знаю, как это сделать

custFormAttrLiteList.forEach((customFormAttributeLite)->
                custNameAndType = new HashMap<Long,Long>();
                custNameAndType.put(customFormAttributeLite.getId(), customFormAttributeLite.getFieldType());

                customNameId.put(customFormAttributeLite.getName(), custNameAndType);
            );

Ответы [ 3 ]

0 голосов
/ 01 февраля 2019

Вы также можете использовать Collectors#groupingBy для этой цели.Сначала сгруппируйте по полю имени, затем сгруппируйте по id и fieldType.

List<CustomFormAttributeLite> custFormAttrLiteList = new ArrayList<>();

Map<String,Map<Long,Long>> customNameId = custFormAttrLiteList.stream()
                        .collect(Collectors.groupingBy(CustomFormAttributeLite::getName,
                         Collectors.toMap(CustomFormAttributeLite::getId, CustomFormAttributeLite::getFieldType)));

Если имена не уникальны, результат не будет таким, как вы ожидаете, поэтому в этом случае нам нужно использовать Collectors.toMap и используйте mergeFunction, чтобы сохранить только вторую неуникальную запись:

Map<String,Map<Long,Long>> customNameIdNonUnique = custFormAttrLiteList.stream()
                    .collect(Collectors.toMap(CustomFormAttributeLite::getName, //key mapper function
                     (obj) -> {Map<Long,Long> map = new HashMap<>(); map.put(obj.getId(), obj.getFieldType()); return map;}, //value mapper function
                     (key1, key2)-> key2)); //retaining only the second entry 

В качестве теста я использовал следующий набор данных для тестирования обоих этих решений:

CustomFormAttributeLite c1 = new CustomFormAttributeLite("foo", 123L, 123L);
CustomFormAttributeLite c2 = new CustomFormAttributeLite("foo", 124L, 125L);
CustomFormAttributeLite c3 = new CustomFormAttributeLite("bar", 125L, 126L);
CustomFormAttributeLite c4 = new CustomFormAttributeLite("bar", 125L, 126L);

Второе решение дало результат:

{bar={125=126}, foo={124=125}}
0 голосов
/ 01 февраля 2019

Я настоятельно рекомендую вам избегать изменения состояния коллекции в forEach.Вместо этого соберите данные, используя .collect(...).

Сначала создайте метод ( static или dynamic ) для сопоставления CustomFormAttributeLite с Map<Long,Long>:

Map<Long,Long> mapToNameAndType(CustomFormAttributeLite attribute){
    Map<Long, Long> map = new HashMap<>();
    map.put(attribute.getId(), attribute.getFieldType());
    return map;
}

Затем вы можете просто собрать данные в новый Map, используя Collectors.toMap():

Map<String, Map<Long, Long>> customNameId = 
    custFormAttrLiteList.stream()                                                                         
                        .collect(toMap(CustomFormAttributeLite::getName,this::mapToNameAndType));
0 голосов
/ 01 февраля 2019

Вы можете использовать только заключительные переменные внутри для каждого лямбда-выражения.Поэтому попробуйте так:

final Map<String,Map<Long,Long>> customNameId = new HashMap<String, Map<Long,Long>>();
custFormAttrLiteList.forEach((customFormAttributeLite)-> {
                Map<Long,Long> custNameAndType = new HashMap<Long,Long>();
                custNameAndType.put(customFormAttributeLite.getId(), customFormAttributeLite.getFieldType());

                customNameId.put(customFormAttributeLite.getName(), custNameAndType);
            });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...