Java (8): как извлечь определенный элемент класса из массива объектов?

Мне нужно работать с массивом объектов, который имеет следующее значение:

objectsArray = {Object[3]@10910} 
 {Class@10294} "class com.ApplicationConfiguration" -> {ApplicationConfiguration@10958} 
    key = {Class@10294} "class com.ApplicationConfiguration"
    value = {ApplicationConfiguration@10958} 
 {Class@10837} "class com.JoongaContextData" -> {JoongaContextData@10960} 
    key = {Class@10837} "class com.JoongaContextData"
    value = {JoongaContextData@10960} 
 {Class@10835} "class com.SecurityContext" -> {SecurityContext@10961} 
    key = {Class@10835} "class com.SecurityContext"
    value = {SecurityContext@10961} 

Код, который создает массив объектов:

public class ProcessDetails {
    private UUID myId;
    private Date startTime;
    private ResultDetails resultDetails;
    private long timeout;
    .
    .
    .
}

public interface ProcessStore extends Map<Class, Object> {
    <T> T unmarshalling(Class<T> var1);

    <T> void marshalling(T var1);

    ProcessDetails getProcessDetails();
}

Object[] objectsArray = processStore.entrySet().toArray();

Мне нужно извлечь значение из элемента типа Конфигурация приложения.

Обратите внимание, что это не всегда первый элемент массива!

Для начала я попытался сделать следующее:

    List<ApplicationConfiguration> ApplicationConfigurations = Arrays.stream(objectsArray)
            .filter(item -> item instanceof ApplicationConfiguration)
            .map(item -> (ApplicationConfiguration)item)
            .collect(Collectors.toList());

чтобы получить список с конкретным элементом. У меня почему-то пустой список.

Почему?

Можете ли вы добавить определение массива объектов?

Benoit 22.05.2019 09:26

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

AxelH 22.05.2019 09:27

Привет, это похоже на пользовательский метод toString(), используемый на карте класса-экземпляра. Не могли бы вы прояснить вопрос, добавив реализацию toString?

Paul Benn 22.05.2019 09:28

@Бенуа добавил код

dushkin 22.05.2019 09:29

Не похоже, чтобы ваш массив содержал экземпляры ApplicationConfiguration в качестве прямых элементов. Он содержит экземпляры некоторых других классов.

Eran 22.05.2019 09:29

Ваш массив Objects[] не содержит экземпляров ApplicationConfiguration. Поэтому вы становитесь пустым списком.

Michal 22.05.2019 09:30

@Michal Ты прав... Он содержит карты... Я проверю...

dushkin 22.05.2019 09:31

Просто подсказка: ваш массив содержит что-то, что имеет key и value

Holger 22.05.2019 09:31
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
8
2 525
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

objectsArray содержит записи карты, и вам необходимо отфильтровать значения этих записей.

List<ApplicationConfiguration> ApplicationConfigurations = 
    Arrays.stream(objectsArray)
          .map(obj -> (Map.Entry<Class, Object>) obj)
          .map(Map.Entry::getValue)
          .filter(item -> item instanceof ApplicationConfiguration)
          .map(item -> (ApplicationConfiguration)item)
          .collect(Collectors.toList());

Конечно, было бы чище, если бы вы изменили

 Object[] objectsArray = processStore.entrySet().toArray();

к

 Map.EntryMap.Entry<Class,Object>[] objectsArray = processStore.entrySet().toArray(new Map.Entry[0]);

чтобы вы могли написать:

List<ApplicationConfiguration> ApplicationConfigurations = 
    Arrays.stream(objectsArray)
          .filter(e -> e.getValue() instanceof ApplicationConfiguration)
          .map(e -> (ApplicationConfiguration) e.getValue())
          .collect(Collectors.toList());

Есть ли способ получить только элемент вместо того, чтобы помещать его в список? Спасибо

dushkin 22.05.2019 10:46

@dushkin Если вы ожидаете, что будет возвращен не более одного элемента, используйте findFirst() вместо collect(). Он вернет Optional<ApplicationConfiguration>.

Eran 22.05.2019 10:47

Этот вызов toArray по-прежнему является непроверенной операцией, поскольку Java на самом деле не поддерживает общие массивы. Более чистым решением было бы вообще не использовать массив, т. е. List<Map.Entry<Class,Object>> list = new ArrayList<>(processStore.entrySet()); имеет преимущество в безопасности во время компиляции, хотя во время выполнения он даже немного быстрее.

Holger 22.05.2019 15:39

Вы пытаетесь найти экземпляры ApplicationConfiguration напрямую в массиве типа Map.Entry<K,V>[], созданном Map#entrySet() и последующим вызовом Set#toArray().

Вместо этого попробуйте следующее:

List<ApplicationConfiguration> boxes = Arrays.stream(objectsArray)
            .map(entry -> ((Map.Entry<Class<?>, Object>) entry))
            .filter(entry -> entry.getKey().isAssignableFrom(ApplicationConfiguration.class))
            .map(Map.Entry::getValue)
            .map(v -> (ApplicationConfiguration) v)
            .collect(Collectors.toList());
entry.getKey() это Class, так что никогда не будет instanceof ApplicationConfiguration
Eran 22.05.2019 09:42

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