Преобразование List <Object> в List <CustomClass> в Java 8

У меня урок:

public class BusinessUnit 
{
    private String name;

  //getter 
  //setter
}

Я получаю List<Object> из службы, который мне нужно преобразовать в List<BusinessUnit>. Данные будут только имя. Но служба возвращает мне Объект. Как лучше всего выполнить это преобразование в Java 8

Лучше всего адаптировать сервис. Список Object действительно не лучший способ предоставить сервисный результат.

M A 22.07.2018 13:11
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
3 589
5

Ответы 5

Ты имеешь в виду :

List<Object> list = ...
List<BusinessUnit> result = list.stream()
        .map(name -> new BusinessUnit((String) name))
        .collect(Collectors.toList());

Я предполагаю, что у вас есть конструктор в BusinessUnit, который принимает neme:

public class BusinessUnit {
    private String name;

    public BusinessUnit(){}

    public BusinessUnit(String name){
       this.name = name;
    }

    //getter 
    //setter
}

Поскольку ваша служба не возвращает строки, вам необходимо просмотреть список и преобразовать их в свой класс BusinessUnit.

List<BusinessUnit> businessUnits = list.stream()
.map(object -> new BusinessUnit(object.toString()))
.collect(Collectors.toList());

В вашем классе BusinessUnit обновите свой метод конструктора

public BusinessUnit(String object){
this.name = object;
}

Я надеюсь это сработает

Он не компилируется

Erwin Bolwidt 22.07.2018 13:26

У меня есть класс Weather, который имеет координаты Map <String, Object> в качестве переменной экземпляра. Теперь я получу List <Weather> из службы. Мне нужно вернуть определенные значения координат dostinct и назначить List <CustomClass> Например. weather.stream.filter (a -> a. getId.equals (id). После метода фильтрации мне нужно получить определенную координату по ее ключу (который я знаю), использовать отдельную функцию и присвоить эти значения List <CustomClass> . CustomClass имеет только имя String в качестве переменной экземпляра, а значение координаты будет иметь тип объекта, но храниться как текст. Как лучше всего сделать это в Java8

Sahil 22.07.2018 13:29
List<BusinessUnit> units = list.stream().map(BusinessUnit.class::cast).collect(Collectors.toList());

Это лучший способ, если вы уверены, что этот объект - BusinessUnit, или если вы можете создать свой метод приведения и проверить там, что это object instanceof BusinessUnit и так далее ..

cast - это метод в Class.java

если какой-то объект String, вы также можете

List<A> a = `list.stream().map(String.class::cast).map(BusinessUnit::new).collect(Collectors.toList());`

Конечно, у вас должен быть единственный конструктор BusinessUnit, принимающий одну строку.

Для этого экземпляра BusinessUnit::new, или вы можете написать что-то вроде этого

.map(s -> new BusinessUnit(...))

обновлено

Вы также можете отфильтровать список объектов, filter(String.class::isInstance), а затем использовать карту.

Взгляните на методы Class.java, есть много интересных и полезных методов.

Если вы знаете, что все элементы являются String, вы можете преобразовать результат службы в List<String>:

List<String> list = (List<String>) service.getData(...);   

И вы также должны попытаться изменить код службы, чтобы он объявлял List<String>, а не необработанный список: List или List<Object> Таким образом вы можете напрямую сопоставить String с BusinessUnit:

List<BusinessUnit> businessUnits =
   list.stream()
       .map(BusinessUnit::new)
       .collect(Collectors.toList));

Где BusinessUnit::new - это конструктор BusinessUnit, который принимает String, как в очень хорошем ответе @YCF_L.

Но если некоторые элементы могут не быть объектами String и вы хотите их исключить (и почему бы не регистрировать информацию), вам следует поступить иначе.

В этом случае хранение List<Object> не вариант:

List<Object> list = service.getData(...);   

Вы должны фильтровать элементы, которые не соответствуют вашим требованиям. Например, здесь я удаляю объекты null, а не String:

List<BusinessUnit> businessUnits =
   list.stream()           
       .map(o -> {
                if (!(o instanceof String)){ 
                   logger.warn(o + "is not a String or is null"); 
                   return null;
                 }
                 return (String) o;
            }
        )
       .filter(Objects::nonNull)
       .collect(Collectors.toList));

Спасибо, YCF :) Нет, здесь нет никакого трюка или магии :) Я просто переделал приведение списка, а не во время обработки потока. Мы проиграли! Как обычно, вы мне ответите :)

davidxxx 22.07.2018 16:25

С Object на String здесь: .map(name -> new BusinessUnit((String) name)).

davidxxx 22.07.2018 16:30

мой плохой я скопировал код другого ответа не мой ответ да я имел в виду .map(name -> new BusinessUnit((String) name))

YCF_L 22.07.2018 16:33

Вы можете добиться этого с помощью концепции Java 8 Stream:

List<BusinessUnit> units = businessUnitsAsObjects.stream()
    .map(BusinessUnit.class::cast)
    .collect(Collectors.toList());

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