标签: pecs

什么是PECS(制作人扩展消费者超级)?

我在阅读泛型时遇到了PECS(制片extends人和消费者的super简称).

能否给我一个人解释如何使用佩奇之间解决困惑extendssuper

java generics super pecs bounded-wildcard

680
推荐指数
11
解决办法
9万
查看次数

带有'超'类型的有界泛型方法

根据我阅读的文献,我们有多汁的实现以下界面:

public interface Juicy<T> {
    Juice<T> squeeze();
}
Run Code Online (Sandbox Code Playgroud)

使用有界类型变量,以下方法将获得一堆水果并将它们全部挤压:

<T extends Juicy<T>> List<Juice<T>> squeeze(List<T> fruits);
Run Code Online (Sandbox Code Playgroud)

现在我们还需要更低级的兄弟姐妹来工作:

class Orange extends Fruit implements Juicy<Orange>;
class RedOrange extends Orange;
Run Code Online (Sandbox Code Playgroud)

所以我希望该方法看起来如下:

<T extends Juicy<T>> List<Juice<? super T>> squeeze(List<? extends T> fruits);
Run Code Online (Sandbox Code Playgroud)

相反,我发现方法签名如下:

<**T extends Juicy<? super T>>** List<Juice<? super T>> squeezeSuperExtends(List<? extends T> fruits);
Run Code Online (Sandbox Code Playgroud)

是什么解释了这种差异

java generics pecs

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

为什么在集合中添加类型的子类a是非法的?

给出这段代码片段

    //Creates a list of List numbers
    List<List<Number>> num = new ArrayList<List<Number>>();
    //Creates a list of List doubles
    List<List<Double>> doub = new ArrayList<List<Double>>();
    //List of doubles
    List<Double> d = new ArrayList<Double>();
    d.add(2.5);
    d.add(2.6);
    doub.add(d);

    num.add(d);//This code will not compile
Run Code Online (Sandbox Code Playgroud)

为什么不允许num.add(doub)?不是List<List<Number>>超级型 List<List<Double>>

java generics wildcard pecs

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

是否可以编写一个接受不同抽象的泛型参数的方法?

作为这个问题后续,是否有可能编写一个方法来增加Dog一个合适的房间?(在这个例子中,它会接受Animal房间或Dog房间.)或者我是否被迫写下两种不同的方法如下?(因为类型擦除,我甚至不能依赖重载).

public class Rooms {
   interface Animal {}
   class Dog implements Animal {}
   class Room<T> {
      void add(T t) {}
   }

   void addDogToAnimalRoom(Room<Animal> room) {
      room.add(new Dog());
   }

   void addDogToDogRoom(Room<Dog> room) {
      room.add(new Dog());
   }   
}
Run Code Online (Sandbox Code Playgroud)

java generics pecs bounded-wildcard

4
推荐指数
1
解决办法
123
查看次数

Java中的泛型生产者和消费者

我有这个方法来检索作为给定类的实例的对象:

public class UtilitiesClass {

    public static final Collection<Animal> get(Collection<Animal> animals, Class<? extends Animal> clazz) {
        // returns the Animals which are an instanceof clazz in animals
    }
...
}
Run Code Online (Sandbox Code Playgroud)

要调用该方法,我可以这样做:

Collection<Animal> dogs = UtilitiesClass.get(animals, Dog.class);
Run Code Online (Sandbox Code Playgroud)

这很好,但我也希望能够通过以下两种方式调用该方法:

Collection<Animal> dogs = UtilitiesClass.get(animals, Dog.class);
Run Code Online (Sandbox Code Playgroud)

要么

Collection<Dog> dogsTyped = UtilitiesClass.get(animals, Dog.class);
Run Code Online (Sandbox Code Playgroud)

我的意思是我希望能够将方法的结果存储在Dog Collection或Animal one中,因为我需要Dog.class扩展Animal.class

我在考虑这样的事情:

public static final <T> Collection<T> get(Class<T extends Animal> clazz) {
    // returns the Animals which are an instanceof clazz
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用.任何提示?

编辑:最后,使用@Rohit Jain答案,这是调用UtilitiesClass方法时的解决方案:

Collection<? extends …
Run Code Online (Sandbox Code Playgroud)

java generics pecs

3
推荐指数
1
解决办法
1350
查看次数

为什么 Comparable 和 Comparator 是 Java 中 PECS 通配符类型的消费者

在Effective Java中,在“使用有界通配符增加API灵活性”一文中,在谈到PECS(producer-extends,consumer-super)的使用时,作者提到:

Comparable 始终是消费者,因此您通常应该使用 Comparable<? super T> 优先于 Comparable。比较器也是如此;因此,您通常应该使用 Comparator<? super T> 优先于比较器。

我不清楚为什么 Comparables 和 Comparator 被认为是消费者。

在讨论 PECS 的主题之一中,什么是 PECS(生产者扩展消费者超级)?,消费者通常将 Collection 称为某个泛型方法的参数。

而这里 Comparable 只是一个接口。

任何人都可以分享一些见解吗?谢谢!

java generics super pecs

3
推荐指数
1
解决办法
185
查看次数

是如何决定谓词“和”方法在java中拥有消费者而不是生产者的?

我正在浏览 java 8 中引入的 Predicate 类,它是函数式接口。Predicate 类中有一个方法和方法,用于将多个谓词组合成一个。

default Predicate<T> and(Predicate<? super T> other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) && other.test(t);
}
Run Code Online (Sandbox Code Playgroud)

我已经阅读了 Java 中 PECS 的概念,但仍然无法理解为什么在 Predicate 的情况下我们使用? super T. Java 程序员如何决定它将成为消费者而不是生产者。

我的意思是为什么不允许出现编译错误的行:

public class PredicateExample {
    public static void main(String[] args) {
        Predicate<Number> pred = n -> n.intValue() > 2;
        Predicate<Integer> predInt = n -> n > 3;
        //Compile error
        //pred.and(predInt);

        Predicate<Object> predObj = o -> Integer.parseInt(o.toString()) > 4;
        pred.and(predObj); //Valid statement

        Number n = new …
Run Code Online (Sandbox Code Playgroud)

java lambda functional-programming java-8 pecs

2
推荐指数
1
解决办法
98
查看次数

如何传递实现同一接口的多个类型?

首先,我对这个不太好的标题表示歉意,我是 Java 新手,不知道如何命名它。

我有一个接口类“TestInterface”:

ublic interface TestInterface {

    String getForename();

    void setForename(String forename);

    String getSurname();

    void setSurname(String surname);
}

Run Code Online (Sandbox Code Playgroud)

“TestImpl”实现“TestInterface”:

public class TestImpl implements TestInterface{

    private String forename;

    private String surname;

    @Override
    public String getForename() {
        return forename;
    }

    public void setForename(String forename) {
        this.forename = forename;
    }

    @Override
    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个名为“ExtendTest”的调用,它扩展了“TestImpl”:

public class ExtendTest extends TestImpl{

    private String firstLineAddress;

    public String getFirstLineAddress() {
        return …
Run Code Online (Sandbox Code Playgroud)

java generics pecs

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