相关疑难解决方法(0)

在返回集合的接口中使用Java泛型.最佳实践?陷阱?

我今天碰到了一些我发现有问题的代码.这是一个简化的例子(不现实).

public interface IListable {
    //returns first n items from list
    public ArrayList getFirstNThings(int n);

    //returns last n items from list
    public ArrayList getLastNThings(int n);
}
Run Code Online (Sandbox Code Playgroud)

然后有一个像这样的实现者:

public GroceryList implements IListable {
    private ArrayList<GroceryItem> groceries;

    public GroceryList() {
        this.groceries = new ArrayList<GroceryItem>();
    }

    public ArrayList<GroceryItem> getFirstNThings(int n) {
        ArrayList<GroceryItem> firstNThings = new ArrayList<GroceryItem>();
        for (int i=0; i < n; i++) {
            firstNThings.add(this.groceries.get(i));
        }
        return firstNThings
     }

     public ArrayList<GroceryItem> getLastNThings(int n) {
         ArrayList<GroceryItem> lastNThings = new ArrayList<GroceryItem>();
         for (int i=this.groceries.size(); i …
Run Code Online (Sandbox Code Playgroud)

java oop generics collections interface

5
推荐指数
1
解决办法
3206
查看次数

Java泛型捕获列表<?>

我正在查看Java Generics文档并找到这段代码,

public class WildcardError {

void foo(List<?> l) {
    //This give a compile time error
    l.set(0,l.get(0));
}
}
Run Code Online (Sandbox Code Playgroud)

我可以理解,我们从a中获取一个元素List<?>并尝试将其设置为另一个元素List<?>.所以编译器会出错.我的问题是,当2个列表不同时,l.set(0, m.get(0))这里列出l并且m不同,这是有道理的.但在上面的例子中,ll列表相同.为什么编译器不够聪明才能看到它?实施起来难吗?

编辑:我知道我可以通过辅助方法或使用T而不是使用?.来修复它.只是想知道为什么编译器不会为我做这件事.

java generics

5
推荐指数
2
解决办法
5020
查看次数

最大元素 - 孙的答案VS我的

在阅读了Sun关于泛型的文档之后,我转到了http://docs.oracle.com/javase/tutorial/java/generics/QandE/generics-questions.html上的Q和E部分.

对于Q8 -

编写一个通用方法来查找列表[begin,end]范围内的最大元素.

我写的代码是:

private static <T extends Comparable<T>> T max(List<T> l, int i, int j) {
    List<T> sublist = l.subList(i, j);
    System.out.println("Sublist "+sublist);
    int c = 0;T max = null;
    for(T elem: sublist) {
        if(c == 0 || max.compareTo(elem) < 0) {
            max = elem;
        } ++c;
    }
    return max;
}
Run Code Online (Sandbox Code Playgroud)

而Sun的回答是:

public static <T extends Object & Comparable<? super T>>

    T max(List<? extends T> list, int begin, int end) {

    T maxElem = list.get(begin);

    for …
Run Code Online (Sandbox Code Playgroud)

java generics

5
推荐指数
1
解决办法
201
查看次数

ArrayList,带有Java中的泛型声明

以下代码给出了该行的错误 l.add

List<? extends Number> l = new ArrayList<Integer>();
l.add(1);
Run Code Online (Sandbox Code Playgroud)

并强迫我把它写成 l.add(1, null);

为什么会这样?

java generics collections

5
推荐指数
2
解决办法
826
查看次数

这究竟是什么意思?扩展E> c

有时候,我很多时候会在文档中看到这种情况.它让我想知道要输入什么.有人可以用明确的愚蠢的文字向我解释这个含义:D.怎么样:

ArrayList(Collection<? extends E> c)
Run Code Online (Sandbox Code Playgroud)

最终用作这个:

new ArrayList<>(Arrays.asList("a","b","c"));
Run Code Online (Sandbox Code Playgroud)

所以我不需要通过谷歌搜索来问这个"问题",而是能够自己解决这个问题.

java javadoc

5
推荐指数
1
解决办法
3310
查看次数

<?的必要性?super T>在Collections.copy中输入

Collections.copy方法签名是,

public static <T> void copy(List<? super T> dest, List<? extends T> src)
Run Code Online (Sandbox Code Playgroud)

只是想知道dest类型是否必须<? super T>而不仅仅是<T>

public static void main(String[] args)
{
  simpleCopy(new ArrayList<Number>(), new ArrayList<Number>());
  simpleCopy(new ArrayList<Number>(), new ArrayList<Integer>());
}

public static <T> void simpleCopy(Collection<T> dest, Collection<?  extends T> src)
{
   for (T element : src)
     dest.add(element);
}
Run Code Online (Sandbox Code Playgroud)

java generics

5
推荐指数
0
解决办法
70
查看次数

什么方法声明接受有界和无界多级泛型?

鉴于:

public class Testcase {

    public static <E> List<List<E>> transform(List<List<E>> list) {
        return list;
    }

    public static <E> List<List<? extends E>> transform2(List<List<? extends E>> list) {
        return list;
    }

    public static void main(String[] args) {
        List<List<Integer>> known = new ArrayList<>();
        List<List<? extends Number>> unknown = new ArrayList<>();

        transform(known);    // works
        transform(unknown);  // fails

        transform2(known);   // fails
        transform2(unknown); // works
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器接受transform(known)但抱怨:

cannot infer type-variable(s) E
    (argument mismatch; List<List<? extends Number>> cannot be converted to List<List<E>>)
  where E …
Run Code Online (Sandbox Code Playgroud)

java bounded-wildcard

5
推荐指数
1
解决办法
60
查看次数

scala中的泛型不变协变逆变

这可能是一个非常愚蠢的问题,但即使在长时间挠头之后我也无法理解这种差异.

我正在浏览scala泛型页面:https://docs.scala-lang.org/tour/generic-classes.html

据说这里

注意:泛型类型的子类型是不变的.这意味着如果我们有一堆Stack [Char]类型的字符,那么它就不能用作Stack [Int]类型的整数堆栈.这将是不合理的,因为它将使我们能够在字符堆栈中输入真正的整数.总之,Stack [A]只是Stack [B]的子类型,当且仅当B = A时.

我完全理解这一点,我无法CharInt需要的地方使用.但是,我的Stack班级只接受A类型(即invariant).如果我把Apple,Banana或Fruit放入其中,它们都会被接受.

class Fruit

class Apple extends Fruit

class Banana extends Fruit

  val stack2 = new Stack[Fruit]
  stack2.push(new Fruit)
  stack2.push(new Banana)
  stack2.push(new Apple)
Run Code Online (Sandbox Code Playgroud)

但是,在下一页(https://docs.scala-lang.org/tour/variances.html)上,它说类型参数应该是协变的+A,那么即使是添加子类型,Fruit示例如何工作呢?invariant.

希望我对我的问题很清楚.如果有更多信息,请告诉我.需要添加.

scala scala-collections

5
推荐指数
1
解决办法
320
查看次数

如何分配List <?将BaseClass>扩展为List <BaseClass>

class BaseClass implements IData ();
class ChildClassA() extends BaseClass;
class ChildClassB() extends BaseClass;
Run Code Online (Sandbox Code Playgroud)

既然做不到

List<BaseClass> aList = new ArrayList<ChildClassA>()
Run Code Online (Sandbox Code Playgroud)

所以有一个

List<? extends IData> aList 
for pointint to either 
    ArrayList<ChildClassA>(),  
or 
    ArrayList<ChildClassB>()
Run Code Online (Sandbox Code Playgroud)

aList是通过其他路由在运行时建立,并且该代码部分具有如下功能:取List<IData>从所述aList

问题是如果List<? extends IData> aList 指向ArrayList<ChildClassA>()ArrayList<ChildClassB>(),

可以ListData<IData> outputList = (List<IData>) aList吗?如下所示:

(似乎它正在工作,但不确定是否有更好的方法来分配除了强制转换之外的泛型数组.)

编辑:输出List<IData> outputList 是为了只读使用(不可变),没有插入/删除,它只会迭代IData以对IData真正的反应作出反应.

List<? extends IData> aList =  new ArrayList<ChildClassA>();
ListData<IData> outputList = (List<IData>)aList

List<? extends IData> aList =  new ArrayList<ChildClassB>();
ListData<IData> …
Run Code Online (Sandbox Code Playgroud)

java generics list-template

5
推荐指数
1
解决办法
116
查看次数

为什么 Java Stream.map 采用 Function&lt;?超级 P_OUT, ? 扩展 R&gt; 映射器作为输入而不是 Function&lt;P_OUT, ? 扩展 R&gt;?

为什么map将其输入作为 aFunction类型<? super P_OUT, ? extends R>而不是<P_OUT, ? extends R>

例如,当我这样做时,

List<Integer> list = new ArrayList<>();
list.stream().map(xyz -> {}); // Here xyz is always of type Integer for this instance. 
                              // Then why does it take input as "? super Integer"?
Run Code Online (Sandbox Code Playgroud)

是不是因为没有限制方法引用?这是唯一的用例吗?

java generics wildcard java-8 java-stream

5
推荐指数
1
解决办法
1052
查看次数