Динамическое приведение объектов из массива объектов к соответствующим классам, доступным в перечислении - PullRequest
0 голосов
/ 08 мая 2018
public class A {
     private String property;
     public String getProperty() {
          return property;
     }
}
public class B {
     private String property;
     public String getProperty() {
          return property;
     }
}

аналогично определены классы C и D. (Опуская другую логику и сложность)

Затем создал перечисление этих имен классов. [Простое имя класса или каноническое имя класса, которое я могу добавить без проблем]

public enum ClassNameEnum{ A, B, C, D }

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

Моя цель: Получите каждый элемент в массиве объектов, приведите их к одному из имен classe в myEnum и выполните вызов метода.

Что я сделал до сих пор. (1) цикл по массиву объектов и, если еще лестница, чтобы проверить instanceof. При совпадении приведите и сделайте операцию [работает, но безобразно]

(2) Улучшение:

public class ImplClass {
    public static void main(String[] args)
    {
        List<Object> objectList = new ArrayList<Object>();
        objectList.add(new B());
        objectList.add(new D());
        objectList.add(new A());

        for (Object object : objectList) {
            Arrays.asList(ClassNameEnum.values()).stream()
            .filter(e -> obj instanceof e)   // Error here: e cannot be resolved to a type
            .map(e -> (e)obj)
            .map("Call getProperty() on the casted object and return the string"); // This is what I want to do
        }
    }
}

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Вместо enum вы можете хранить классы в структуре вроде:

class ClassInfo<T> {
    private final Class<T> clazz;
    private final Function<T, String> function;

    // all args constructor here

    String castAndApply(Object obj) {
        return function.apply(clazz.cast(obj));
    }
}

затем создайте карту, например:

Map<Class, ClassInfo> classInfos = Map.of(
  A.class, new ClassInfo<>(A.class, A::getA),
  B.class, new ClassInfo<>(B.class, B::getB),
  C.class, new ClassInfo<>(C.class, C::getProperty)
);

и ниже - использование:

objectList.stream()
        .filter(obj -> classInfos.containsKey(obj.getClass()))
        .map(obj -> classInfos.get(obj.getClass()).castAndApply(obj))
        .forEach(System.out::println);
0 голосов
/ 09 мая 2018

Поскольку вы хотите вызывать общий метод для всех ваших объектов, имеет смысл создать здесь интерфейс.

public interface Property {
   String getProperty();
}

А в вашем классе:

public class A implement Property {
   private String property;

   @Override
   public String getProperty() {
          return property;
   }
}

Попробуйте сохранить ваш объект по ссылке на интерфейс:

List<Property> objectList = new ArrayList<>();
objectList.add(new A());
objectList.add(new B());
...

И наконец:

objectList.forEach(o -> System.out.println(o.getProperty()));
...