如何从Java中的函数返回通用Collection?

时间:2018-08-31 12:53:27

标签: java generics

因此,我可以遍历这段代码,这是Java中通用方法的演示:

public static <T> T addAndReturn(T element, Collection<T> collection){
    collection.add(element);
    return element;
}

....

String stringElement = "stringElement";
List<String> stringList = new ArrayList<String>();
String theElement = addAndReturn(stringElement, stringList); 

但是我不想返回元素,而是要发回整个集合对象。我尝试了几种给定返回类型作为Collection的方法,但是以某种方式不起作用,

public static <T> Collection<T> addAndReturn(T element, Collection<T> collection) {
        collection.add(element);
        System.out.println(collection);
        return collection;
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        // your code goes here
        String stringElement = "stringElement";
        List<String> strList = new ArrayList<String>();

        ArrayList<String> strRes = addAndReturn(stringElement, strList);
        System.out.println(strRes);
    }

并收到此错误:

  

Main.java:22:错误:不兼容的类型:没有类型的实例   存在变量T,以便Collection符合   ArrayList ArrayList strRes =   addAndReturn(stringElement,strList);                                                ^其中T是类型变量:       T扩展了在方法addAndReturn(T,Collection)1中声明的对象错误

有人可以帮助我解决问题吗?

  

代码示例来自Jenkov.com

4 个答案:

答案 0 :(得分:5)

根据OP的评论进行编辑:必须理解ArrayList源自Collection。因此,当方法的接口返回Collection<T>时,当然,您只能将结果分配给Collection,而不能分配给List / ArrayList。您不知道传入List实例的事实。编译器只会看到Collection回来了!

回到第一个问题:您的代码正在返回添加的元素:

public static <T> T addAndReturn(T element, Collection<T> collection){
    collection.add(element);
    return element;
}

只需更改签名和返回的内容:

public static <T> Collection<T> addAndReturn(T element, Collection<T> collection){
    collection.add(element);
    return collection;
}

完成了吗?不是。

如:这不是一个好习惯。返回以参数形式出现的内容会很快导致代码阅读者感到困惑。使读者感到困惑是一件不好的事情。

除此之外:整个方法本身就是伪造的本身,因为该方法的调用者也可以只写:

thatCollection.add(thatElement);

自己。您的方法不会为上述方法添加任何值!对于读者而言,这相当模糊。

为什么有人要写:

addAndReturn(someX, listOfXes);

代替

listOfXes.add(someX);

如果要这样做:

addAndReturn(someX, listOfXes).addAndReturn(someOtherX, listOfXes);

您宁愿去

listOfXes.addAll(Arrays.asList(someX, someOtherX));

例如。不要为可以使用标准库调用处理的事情发明“实用程序”。

答案 1 :(得分:1)

这是您要寻找的吗?

public static <T> Collection<T> addAndReturn(T element, Collection<T> collection) {
    collection.add(element);
    return collection;
}

答案 2 :(得分:1)

类似于下面的清单。

public static <T> Collection<T> addAndReturn(final T element, final Collection<T> collection) {
    collection.add(element);
    return collection;
}

@Test
public void test() {
    final String stringElement = "stringElement";
    final List<String> stringList = new ArrayList<String>();
    final List<String> nextList = (List<String>) addAndReturn(stringElement, stringList);
    assertThat(nextList.get(0), is(equalTo(stringElement)));
}

您只需关心正确的返回参数Collection<T>。 如果想要从子类或列表final List<String> nextList = (List<String>) addAndReturn(stringElement, stringList);之类的接口中进行转换,则可能必须强制转换。

答案 3 :(得分:1)

错误消息指向此行:

ArrayList<String> strRes = addAndReturn(stringElement, strList);

这是在告诉您(使用非Compilerese普通英语),它找不到允许该分配发生的通用类型。

您的方法返回一个Collection<T>(在这种情况下为Collection<String>)。 Collection<String>不是ArrayList<String>的子类型,因此,您不允许将Collection<String>类型的对象分配给ArrayList<String>类型的字段。您的方法返回一个Collection<String>,所以最简单的解决方法是将其分配给类型为Collection<String>的字段:

Collection<String> strRes = addAndReturn(stringElement, strList);

或者,您可以使用局部变量类型推断(假设您使用的是Java的当前版本):

var strRes = addAndReturn(stringElement, strList);