Как мне вернуть List <String>из метода, куда я отправил положить (Object) на карту (получил пример) - PullRequest
0 голосов
/ 14 сентября 2009

У меня есть следующий код

private Map<KEY, Object> values = new HashMap<KEY, Object>();

public void set(KEY key, Object value) {
    values.put(key, value);
}

private Object getObj(KEY key) {
    return values.get(key) == null ? key.getDefaultValue() : values.get(key);
}

public List<E> getList(KEY key) {
    return (List<E>) getObj(key);
}

Идея иметь возможность отправлять любые объекты на карте и затем извлекать ее, но как мне решить составную часть в java?

Вот пример кода. Здесь я сохраняю Список на карту:

    List<String> list = new ArrayList<String>();

    list.add("a string");

    session.set(KEY.LIST, list);

Теперь я хочу снова получить список:

List<String> list = session.getList(KEY.LIST);

Но теперь я получаю

cannot convert from List<E> to List<String>

ошибка по понятным причинам.

Можно ли получить метод List (String) без каких-либо типов? Является ли этот метод правильным?

public List<E> getList(KEY key) {
    return (List<E>) getObj(key);
}

Ответы [ 5 ]

2 голосов
/ 14 сентября 2009

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

2 голосов
/ 14 сентября 2009

Приведенный вами акт будет генерировать предупреждение, потому что на самом деле не проверяет ничего, кроме этого getObj возвращает List. Фактически, нет ничего, что вы можете действительно проверить эффективно, из-за стирания типа - во время выполнения у вас будет List, который содержит строки, но это все.

Вы, конечно, можете проверить, что все в списке является строкой (или нулем), но это операция O (n). Или вы можете просто выполнить приведение, подавить предупреждение и надежду ... в этом случае вы получите исключение только в том случае, если вы нажмете не строку.

1 голос
/ 14 сентября 2009

Вы можете попробовать MultiMap. Вы можете хранить несколько значений для каждого ключа. У Google есть реализация . Apache commons, вероятно, также имеет реализацию.

0 голосов
/ 14 сентября 2009

Еще один способ преодолеть стирание типа * - передать ссылку на класс объекта, который вы ожидаете в возвращении.

У вас также есть возможность проверить некоторые типы.

public <E> List<E> getList(KEY key, Class<? extends E> elementClass)
{
  Object o = getObj(key);
  if ( ! (o instanceof List) ) throw new RuntimeException("Not a list value");
  List l = (List)o;
  if ( l.size() > 0 && !elementClass.isAssignableFrom( l.get(0) ) ) throw new RuntimeException("List element not valid type");

  return (List<E>)l;
}

Вы бы назвали это как:

List<String> list = session.getList(KEY.LIST, String.class);

* по крайней мере преодолеть стирание типа в объявлении метода. Вам все еще нужно выполнить приведение в теле метода.

0 голосов
/ 14 сентября 2009

Вместо ввода List в сеанс введите тип, который имеет смысл в области приложения. Например, вместо List<LineItem> используйте Order:

public final class Order {
    private final List<LineItem> lineItems;
    [...]
}
...