Как безопасно преобразовать java объект в общую коллекцию c? - PullRequest
0 голосов
/ 19 марта 2020

Я могу безопасно приводить простые java объекты, выполняя что-то вроде:

Object str = "test";
Optional.of(str)
      .filter(value -> value instanceof String)
      .map(String.class::cast)
      .ifPresent(value -> System.out.println("Here is the value: " + value));

Но как я могу сделать такой же объект приведения материала к обобщенной c коллекции?

Например:

Object entries = /**/;
// this is unsafe
List<Entry<String, String>> subscriptions = (List<Entry<String, String>>) entries;

Как мне справиться с подобной ситуацией, и есть ли какая-либо библиотека (что-то вроде ClassCastUtils), чтобы помочь с таким преобразованием?

1 Ответ

1 голос
/ 19 марта 2020

Не очень хороший способ сделать это. Наивный подход был бы к

  1. Проверьте, что это список / набор / коллекция
  2. Проверьте все элементы Entry s
  3. Проверьте все ключи и значения из каждого Entry являются String s

Например,

Map<String, String> map = new HashMap<>();
map.put("a", "b");
Object entries = map.entrySet();

boolean safe = Optional.of(entries)
    .filter(Set.class::isInstance)
    .map(e -> (Set<?>) e)
    .filter(set -> set.stream().allMatch(Map.Entry.class::isInstance))
    .map(e -> (Set<Map.Entry<?, ?>>) e)
    .filter(set -> set.stream().allMatch(e -> e.getKey() instanceof String && e.getValue() instanceof String))
    .isPresent();

Однако даже это не дает достаточной уверенности. Предположим, что карта была объявлена ​​как:

Map<String, Object> map = new HashMap<>();
map.put("a", "b");

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

map.add("b", 123);

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

Вы можете обойти это несколькими способами:

  1. Глубокая копия всей коллекции после проверки. Но как насчет состояния гонки после проверки перед копированием? Вам придется использовать блокировку.
  2. Сделать карту неизменной

Как насчет того, если это коллекция, но в настоящее время она пуста? В этом случае вы не можете делать какие-либо проверки на предметах.

Как видите, работа с таким составом - очень тяжелая работа, и во многих местах вы можете потенциально go ошибиться. Лучше всего избегать таких бросков.

...