Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy a generic Collection in Java using wildcards

Tags:

java

generics

Consider this java class:

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;


public class NumberSet {

    private Collection<? extends Number> numbers;

    public NumberSet(Collection<? extends Number> numbers) {
        this.numbers = numbers;
    }

    public NumberSet(NumberSet other) {

        //copy other.numbers to this.numbers
        numbers = new LinkedList<>();
        for (Iterator<? extends Number> it = other.numbers.iterator(); it.hasNext();) {
            numbers.add(it.next()); // Here's Syntax Error near `it.next()`
        }

    }
}

There is This Syntax Error inside for loop:

actual argument Number cannot be converted to CAP#1 by method invocation conversion
where E is a type-variable:
    E extends Object declared in interface Collection
where CAP#1 is a fresh type-variable:
    CAP#1 extends Number from capture of ? extends Number

I Understand the meaning of PECS but I want to implement a copy-constructor for this class. the copied instance would be used Just as an snapshot of other. any Idea?

like image 960
Mostafa Nazari Avatar asked Jun 16 '15 16:06

Mostafa Nazari


People also ask

How do you use generic wildcards?

Guidelines for Wildcards. Upper bound wildcard − If a variable is of in category, use extends keyword with wildcard. Lower bound wildcard − If a variable is of out category, use super keyword with wildcard. Unbounded wildcard − If a variable can be accessed using Object class method then use an unbound wildcard.

What is a generic wildcard?

The question mark (?) is known as the wildcard in generic programming. It represents an unknown type. The wildcard can be used in a variety of situations such as the type of a parameter, field, or local variable; sometimes as a return type.

What is the difference between generics and wildcards in Java?

Wildcards are nothing but the question mark(?) that you use in the Java Generics. We can use the Java Wildcard as a local variable, parameter, field or as a return type. But, when the generic class is instantiated or when a generic method is called, we can't use wildcards.

What is the syntax for wildcard in Java?

In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).


1 Answers

Change :

 Collection<? extends Number> dst 

To :

 Collection<? super Number> dst

Addition is not allowed using ? extends. There is something known as the Get and Put principle. Quoting from the Generics and Collections book from Philip Wadler :

The Get and Put Principle: use an extends wildcard when you only get values out of a structure, use a super wildcard when you only put values into a structure, and don’t use a wildcard when you both get and put

Also take a look at PECS for a more common explanation of this phenomenon. (However, I prefer the GET and PUT principle over the Producer and Consumer principle as it is less confusing)

like image 189
Chetan Kinger Avatar answered Sep 20 '22 20:09

Chetan Kinger