相关疑难解决方法(0)

通用类型的ArrayList和接口继承问题

我无法理解为什么以下不起作用,我确信答案与我不理解的基本相关,并希望有人可以提供帮助.

我理解如何使用接口ArrayList,如果我有:

public interface Weapon { ... }
public class Gun implements Weapon { ...}
public class Knife implements Weapon { ... }
Run Code Online (Sandbox Code Playgroud)

然后,您可以将实施武器的任何东西插入到武器数组中:

ArrayList<Weapon> weapons = new ArrayList<Weapon>();
weapons.add(new Gun());
weapons.add(new Knife();
Run Code Online (Sandbox Code Playgroud)

我明白了,但令我困惑的是理解为什么ArrayList<Gun>ArrayList<Weapon>其他方面不兼容.为了说明,以下是合法的:

public void interfaceIsTheArgument(Weapon w) { ... }
...
interfaceIsTheArgument(new Gun());
interfaceIsTheArgument(new Knife());
Run Code Online (Sandbox Code Playgroud)

但以下不是:

public void interfaceIsTheArgument(ArrayList<Weapon> w) { ... }
...
interfaceIsTheArgument(new ArrayList<Gun>());
interfaceIsTheArgument(new ArrayList<Knife>());
Run Code Online (Sandbox Code Playgroud)

因为最后一个函数调用报告该方法不适用于其参数.

我的问题是,如果方法知道它的任务是ArrayList一个接口作为泛型类型,为什么不能在最后一个语句中传入一个数组的刀具列表?

java generics collections types subclass

7
推荐指数
1
解决办法
2926
查看次数

Java泛型集合,无法将列表添加到列表中

为什么如下

public class ListBox {
    private Random random = new Random();
    private List<? extends Collection<Object>> box;

public ListBox() {
    box = new ArrayList<>();
}

public void addTwoForks() {
    int sizeOne = random.nextInt(1000);
    int sizeTwo = random.nextInt(1000);

    ArrayList<Object> one = new ArrayList<>(sizeOne);
    ArrayList<Object> two = new ArrayList<>(sizeTwo);

    box.add(one);
    box.add(two);
}

public static void main(String[] args) {
    new ListBox().addTwoForks();
}
}
Run Code Online (Sandbox Code Playgroud)

不行?为了学习的目的只是用泛型来玩,我希望我能够在那里插入任何扩展Collection的东西,但是我得到了这个错误:

The method add(capture#2-of ? extends Collection<Object>) in the type List<capture#2-of ? extends Collection<Object>> is not applicable for the arguments (ArrayList<Object>) …
Run Code Online (Sandbox Code Playgroud)

java generics collections

7
推荐指数
1
解决办法
1468
查看次数

通用vs通配符未知类型

什么时候建议做:

public <E> boolean hasPropertyX(List<E extends User> alist);
Run Code Online (Sandbox Code Playgroud)

public boolean hasPropertyX(List<? extends User> alist);
Run Code Online (Sandbox Code Playgroud)

看起来它们的效果也一样好.

java generics wildcard

7
推荐指数
1
解决办法
447
查看次数

如何声明泛型处理程序的泛型multitype集合

我总是很难将泛型与集合和通配符一起使用.

所以这是以下地图.我想保留特定类型的数据包类的处理程序集合.

private ConcurrentHashMap<Class<? extends Packet>, List<PacketListener<? extends Packet>>> listeners = new ConcurrentHashMap<>();
Run Code Online (Sandbox Code Playgroud)

而且 PacketListener

public interface PacketListener<T extends Packet> {

    public void onOutgoingPacket(Streamer streamer, T packet);

    public void onIncomingPacket(Streamer streamer, T packet);
}
Run Code Online (Sandbox Code Playgroud)

现在我想做的是根据传入的数据包类获取侦听器,如下所示:

public <T extends Packet> void addPacketListener(Class<T> clazz, PacketListener<T> listener) {
    if (listeners.containsKey(clazz) == false) {
        listeners.putIfAbsent(clazz, new LinkedList<PacketListener<T>>());  // ERROR
    }
    List<PacketListener<? extends Packet>> list = listeners.get(clazz);
    list.add(listener);
}

public <T extends Packet> List<PacketListener<T>> getPacketListeners(Class<T> clazz) {
    List<PacketListener<T>> list = listeners.get(clazz);// ERROR
    if (list == …
Run Code Online (Sandbox Code Playgroud)

java generics

7
推荐指数
1
解决办法
511
查看次数

通用方法调用

我有这段代码来自"Java - 初学者指南 - Schildt",第13章:

package com.chapter.thirteen;

public class GenericMethodDemo {
static <T extends Comparable<T>, V extends T> boolean arraysEqual(T[] x, V[] y){
    if(x.length != y.length) return false;

    for(int i = 0; i < x.length; i++)
        if(!x[i].equals(y[i])) return false;

    return true;
}

public static void main(String args[]){

    Integer [] nums  = { 1, 3, 3, 4, 6 };
    Integer [] nums2 = { 1, 3, 3, 4, 6 };
    Integer [] nums3 = { 1, 3, 3, 4, 6 }; …
Run Code Online (Sandbox Code Playgroud)

java generics

7
推荐指数
1
解决办法
140
查看次数

泛型 - 下限/上限外卡行为?

我试图了解低级和上级通配符的行为.

尝试编译以下代码时遇到问题.

Collection<? extends Object> c = new ArrayList<Object>();
c.add(new Object()); // Compile time error
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我也尝试了下限外卡.幸运或不幸的是,代码编译得很好但却造成了很多混乱.

Collection<? super Object> c = new ArrayList<Object>();
 c.add(new Object()); // Compiles fine
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下,这两个代码片段是如何工作的.如果有人可以提供其他示例/链接,那就太好了.

如果我上面做错了,请纠正我.

提前致谢.

java generics

7
推荐指数
1
解决办法
591
查看次数

为什么kotlin不允许协变mutablemap成为委托?

我是Kotlin的新手.当我在地图中学习存储属性时.我尝试以下用法.

class User(val map: MutableMap<String, String>) {
    val name: String by map
}
Run Code Online (Sandbox Code Playgroud)

class User(val map: MutableMap<String, in String>) {
    val name: String by map
}
Run Code Online (Sandbox Code Playgroud)

class User(val map: MutableMap<String, out String>) {
    val name: String by map
}
Run Code Online (Sandbox Code Playgroud)

前两个都是工作,最后一个都失败了.使用out修饰符,字节码getName如下:

  public final java.lang.String getName();
     0  aload_0 [this]
     1  getfield kotl.User.name$delegate : java.util.Map [11]
     4  astore_1
     5  aload_0 [this]
     6  astore_2
     7  getstatic kotl.User.$$delegatedProperties : kotlin.reflect.KProperty[] [15]
    10  iconst_0
    11  aaload
    12  astore_3 …
Run Code Online (Sandbox Code Playgroud)

delegates jvm generic-variance kotlin

7
推荐指数
1
解决办法
357
查看次数

Java 8 Comparator比较静态函数

对于Comparator类中的比较源代码

    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
    {
      Objects.requireNonNull(keyExtractor);
      return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }
Run Code Online (Sandbox Code Playgroud)

我明白之间的差别superextends.我不明白的是,为什么这种方法有它们.有人能举例说明参数看起来像什么时无法实现的Function<T, U> keyExtractor

例如 :

Comparator<Employee> employeeNameComparator = Comparator.comparing(Employee::getName);
Run Code Online (Sandbox Code Playgroud)

也可以使用以下函数定义进行编译

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
    Function<T, U> keyExtractor)
{
  Objects.requireNonNull(keyExtractor);
  return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
Run Code Online (Sandbox Code Playgroud)

java generics bounded-wildcard

7
推荐指数
2
解决办法
556
查看次数

带有问号的通用列表类型

我无法解释/理解Java List的泛型类型:

List<? extends Command> myVar = client.performAction(actionParams);
Run Code Online (Sandbox Code Playgroud)

如何? extends Command调用泛型类型,就像它有一个名称一样?究竟是什么类型的?它是一个Command对象吗?或者这是否意味着它只接受扩展的类Command?使用这种结构有什么优势?在什么Java版本中集成了这种类型的构造?

java

7
推荐指数
1
解决办法
612
查看次数

避免在基于工厂的通用MVP框架中进行转换

我试图在MVP模式中实现一种将View和Presenter分离的方法,以提供一个框架,这正是这样做的,但在一点之后我感到困惑.

背景

我有一个View接口,其中包含连接的演示者的泛型类型,反之亦然.这些接口将由实现开发人员扩展.具体的界面对这个问题不感兴趣,但这些界面的类定义如下所示:

public interface Presenter<T extends View>
Run Code Online (Sandbox Code Playgroud)

public interface View<T extends Presenter>
Run Code Online (Sandbox Code Playgroud)

这个想法是View和Presenter都知道对立的界面.

对于使用此结构,开发人员应提供工厂,实例化他想要显示的视图和处理此视图的Presenter.他把它们都给了一个名为SuperController的类.它们与View的类相关联.

创建Presenter的PresenterFactory接口没有参数,并返回Presenter实现,并查看以下内容:

public interface PresenterFactory<T extends View> {

    <S extends Presenter<T>> S create();

}
Run Code Online (Sandbox Code Playgroud)

创建View的ViewFactory接口基于Presenter创建View实现,并查看以下内容:

public interface ViewFactory<T extends View, S extends Presenter<T>> {

    T create(S presenter);

}
Run Code Online (Sandbox Code Playgroud)

问题

我遇到的问题如下:

我想提供一个TestView和TestPresenter的示例.那些看起来像这样:

public interface TestPresenter extends Presenter<TestView> {...}

public interface TestView extends View<TestPresenter> {...}
Run Code Online (Sandbox Code Playgroud)

此外,还提供了ViewFactory,如下所示:

class TestViewFactory implements ViewFactory<TestView, TestPresenter> {

    @Override
    public TestView create(TestPresenter presenter) {
        return new TestViewImpl(presenter);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是TestPresenterFactory:

private class TestPresenterFactory …
Run Code Online (Sandbox Code Playgroud)

java generics mvp software-design

7
推荐指数
1
解决办法
340
查看次数