Как сохранить значения в Hashmap (разделенные запятыми) с одним и тем же ключом, используя Java Stream API?

У меня есть объект с именем EntityObjectDTO, как показано ниже:

 public @Data class EntityObjectDTO  {
     @JsonInclude(JsonInclude.Include.NON_NULL)
     @JsonIgnoreProperties(ignoreUnknown = true)
     @Data
     public static class Attributes {

         private String name;

         private AttributeType attributeType;

         private String dataType;

     }
}

Этот AttributeType является перечислением и может иметь значения (RAW, REFERRED, ORIGINAL). Я пытаюсь сохранить все имена атрибутов и тип данных в хэш-карте строкового ключа и значения. Этот тип данных также может дублироваться.
Вход:

    EntityObjectDTO  obj= new EntityObjectDTO ();
    obj.getAttributes().setName("name1");
    obj.getAttributes().setAttributeType(REFERRED);
    obj.getAttributes().setDataType("Vehicle");

    obj.getAttributes().setName("name2");
    obj.getAttributes().setAttributeType(REFERRED);
    obj.getAttributes().setDataType("Vehicle");

    obj.getAttributes().setName("name3");
    obj.getAttributes().setAttributeType(REFERRED);
    obj.getAttributes().setDataType("Person");
 

Ожидается в HashMap:

{"Автомобиль","имя1,имя2"}
{"Человек","имя3"}

Вот что я пробовал:

      Map<String, String> myMap = obj.getAttributes().stream()
            .filter(entity -> AttributeType.REFERRED.equals(entity.getAttributeType()))
            .collect(Collectors.toMap(EntityObjectDTO.Attributes::getDataType, e -> e.getName()));<br/>

Но при этом я получаю: java.lang.IllegalStateException: Message: Duplicate key Vehicle (попытка объединения значений name1 и name2)

Как добиться ожидаемого результата, внеся некоторые изменения в существующий код?

Измените последнюю строку на .collect(Collectors.toMap(EntityObjectDTO.Attributes::getDat‌​aType, e -> e.getName(),(s1,s2) -> String.join(",",s1,s2)));

Prasanna 18.12.2020 17:28
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
Что такое управление транзакциями JDBC и как оно используется для поддержания согласованности данных?
Что такое управление транзакциями JDBC и как оно используется для поддержания согласованности данных?
Управление транзакциями JDBC - это мощная функция, которая позволяет рассматривать группу операций с базой данных как единую единицу работы. Оно...
Выполнение HTTP-запроса с помощью Spring WebClient: GET
Выполнение HTTP-запроса с помощью Spring WebClient: GET
WebClient - это реактивный веб-клиент, представленный в Spring 5. Это реактивное, неблокирующее решение, работающее по протоколу HTTP/1.1.
Gradle за прокси-сервером
Gradle за прокси-сервером
Создайте проект Gradle под сетевым прокси.
1
1
295
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я понимаю, вашему классу EntityObjectDTO нужен набор атрибутов (список), которых у вас нет, как вы упомянули, я изменил его, как показано ниже, и получил результат, который вам нужен.

Выход : {Автомобиль=имя1,имя2, Человек=имя3}

public @Data class EntityObjectDTO  {
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonIgnoreProperties(ignoreUnknown = true)
    private List<Attributes> attributes = new ArrayList<>();
}

@Data
public class Attributes {

    private String name;

    private AttributeType attributeType;

    private String dataType;

}

public class Main22 {

    public static void main(String[] args) {
        System.out.println("******************");
        EntityObjectDTO  obj= new EntityObjectDTO ();

        Attributes attributes = new Attributes();
        attributes.setName("name1");
        attributes.setAttributeType(REFERRED);
        attributes.setDataType("Vehicle");
        obj.getAttributes().add(attributes);

        attributes = new Attributes();
        attributes.setName("name2");
        attributes.setAttributeType(REFERRED);
        attributes.setDataType("Vehicle");
        obj.getAttributes().add(attributes);

        attributes = new Attributes();
        attributes.setName("name3");
        attributes.setAttributeType(REFERRED);
        attributes.setDataType("Person");
        obj.getAttributes().add(attributes);

        Map<String, String> myMap = new HashMap<>();
        for(Attributes att : obj.getAttributes()){
            if (myMap.containsKey(att.getDataType())) {
                myMap.put(att.getDataType(), myMap.get(att.getDataType())+","+att.getName());
            }else {
                myMap.put(att.getDataType(), att.getName());
            }
        }

        System.out.println(myMap);
    }
}

Это тоже работает, но я предпочитаю java8 Stream API. В любом случае, спасибо!

Raj_91 21.12.2020 12:31
Ответ принят как подходящий

Я предполагаю, что ваш EntityObjectDTO, как показано ниже,

public class EntityObjectDTO {

    private Attributes attributes;

    public Attributes getAttributes() {
        return attributes;
    }

    public void setAttributes(Attributes attributes) {
        this.attributes = attributes;
    }
}

и Attributes, как показано ниже,

public class Attributes {
    private String name;
    private String dataType;
    private AttributeType attributeType;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDataType() {
        return dataType;
    }

    public void setDataType(String dataType) {
        this.dataType = dataType;
    }

    public AttributeType getAttributeType() {
        return attributeType;
    }

    public void setAttributeType(AttributeType attributeType) {
        this.attributeType = attributeType;
    }
}

Тогда вам подходит нижеприведенное,

 public static void main(String[] args) {
            EntityObjectDTO obj= new EntityObjectDTO ();

            Attributes attributes = new Attributes();
            attributes.setName("name1");
            attributes.setDataType("Vehicle");
            attributes.setAttributeType(AttributeType.REFERRED);
            obj.setAttributes(attributes);

            Attributes attributes1 = new Attributes();
            attributes1.setName("name2");
            attributes1.setDataType("Vehicle");
            attributes1.setAttributeType(AttributeType.REFERRED);
            obj.setAttributes(attributes1);


            Attributes attributes2 = new Attributes();
            attributes2.setName("name3");
            attributes2.setDataType("Person");
            attributes2.setAttributeType(AttributeType.REFERRED);
            obj.setAttributes(attributes2);


            List<Attributes> list = List.of(attributes1, attributes2, attributes);

            Map<String, String> collect = list.stream()
                                              .filter(e -> AttributeType.REFERRED.equals(e.getAttributeType()))
                                              .collect(Collectors.groupingBy(Attributes::getDataType,
                                                      Collectors.mapping(Attributes::getName,
                                                              Collectors.joining(","))));

            System.out.println(collect);

}

Обратите внимание, что я использовал отдельный класс.

Другие вопросы по теме