Java 如何从我发送到 put(Object) 到地图中的方法返回 List<String> (得到示例)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1422448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:54:43  来源:igfitidea点击:

How do I return List<String> from a method where I sent to put(Object) into a map (got example)

javagenericslistobjectmap

提问by corgrath

I have the following code

我有以下代码

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);
}

The idea to be able to send in any Objects in a map and then retrieve it, but how do I solve the genereics-part in java?

能够在地图中发送任何对象然后检索它的想法,但我如何解决 java 中的泛型部分?

Here is an example code. Here I save the List into the map:

这是一个示例代码。在这里,我将列表保存到地图中:

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

    list.add("a string");

    session.set(KEY.LIST, list);

Now I want to get the List again:

现在我想再次获取列表:

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

But now I get a

但现在我得到了

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

error for obvious reasons.

错误原因显而易见。

Is it possible to get a List(String) from the method, without any typecasts? Is this method correct?

是否可以从该方法中获取一个 List(String) 而没有任何类型转换?这个方法正确吗?

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

采纳答案by Trevor Harrison

Another option to overcome type erasure* is to pass a reference to the object class that you are expecting in the return.

克服类型擦除*的另一种选择是传递对您期望在返回中的对象类的引用。

You also get a chance to do some type checking.

您还有机会进行一些类型检查。

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;
}

You would call this like:

你会这样称呼它:

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

*at least overcome type erasure in the declaration of the method. You still have to do some casting in the method body.

*至少克服了方法声明中的类型擦除。您仍然需要在方法主体中进行一些转换。

回答by Jon Skeet

The cast you've given will generate a warning, because it's not reallychecking anything other than that getObjreturns a List. In fact, there's nothing you canreally check efficiently, due to type erasure- at execution time, you'll have a Listwhich happens to contain strings, but that's all.

您给出的演员表将产生警告,因为它并没有真正检查除getObj返回List. 事实上,由于类型擦除,没有什么可以真正有效地检查- 在执行时,您将有一个which 恰好包含字符串,但仅此而已。List

You could certainly check that everything in the list isa string (or null) but that's an O(n) operation. Or you could just do the cast, suppress the warning and hope... in which case you'll only get an exception if and when you hit a non-string.

您当然可以检查列表中的所有内容是否都是字符串(或空值),但这是 O(n) 操作。或者你可以只做演员表,压制警告和希望......在这种情况下,如果你击中非字符串,你只会得到一个例外。

回答by Jo?o Silva

You can't solve that because of type erasure. The best you can do is to supress the warning, if you are absolutely sure that the cast can't go wrong.

由于类型擦除,您无法解决该问题。如果您绝对确定演员表不会出错,那么您能做的最好的事情就是抑制警告。

回答by Tom Hawtin - tackline

Instead of putting a Listin the session, introduce a type that makes sense in the application domain. For example instead of List<LineItem>, use Order:

不是List在会话中放置 a ,而是引入在应用程序域中有意义的类型。例如,代替List<LineItem>,使用Order

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

回答by Trevor Harrison

You could try a MultiMap. You can store multiple values per key. Google has an implementation. Apache commons probably has an implementation also.

您可以尝试使用 MultiMap。您可以为每个键存储多个值。谷歌有一个实现。Apache commons 可能也有一个实现。