0

I am currently learning the Generics and I got a task where I have to make an Array class with T type-parameter and an array data member and some methods (setItem, getItem, visitor, condition and addAll). I have problem with the addAll method:

public class Array<T> {
   private T[] array;

   public Array(T[] array){
      this.array = array;
   }

   public void setItem(int i, T item){
      if (i < 0 || i > array.length) {
        System.out.println("There is no this value in the array!");
      }
      array[i] = item;
   }

   public T getItem(int i){
       if (i < 0 || i > array.length) {    
          System.out.println("There is no this item in the array!"); 
       } 
       return array[i];  
   }

   public <E> boolean addAll(Collection<? extends E> c){
       boolean modified = false;
       for (E e : c){
           if (c.add(e)){
               modified = true;
           } 
       }
       return modified;
   }
}

The NB doesn’t accept the e in add method. I cannot figure out why…. If I use T type-parameter instead of E in the method (public boolean addAll(Collection<? extends T>c){} ) the situation is the same. I’ve got message that Incompatible types: E cannot be converted to CAP#1, where E is a type-variable, and CAP#1 is a fresh type-variable. What am I doing wrong?

My 2nd problem is with Array class used an abstract Condition class and it has 6 subclasses. The andCondition, orCondition and so on is OK, but the greaterCondition and doubleCondition do not work. I know where the problem is coming from, but I could not find a solution for that. First of all I used only <T> after classname and than try the following <T extends Number>, but no change:

public abstract class Condition<T> {
    public abstract boolean condition(T item);
}

public class doubleCondition<T extends Number> extends Condition<T> {

    public DoubleCondition (){   
    }

    @Override
    public boolean condition(T item) {
       if (item % 2 == 0){
           return true;
       }
       return false;
   }

I’ve got message: bad operand types for binary operator %, first type: T, second type: int, where T is a type-variable. What should I do with type-parameters or with boolean condition method that I be able to check that the item in the parameters can be divide with 2 without left, so it is double/couple.

And the greaterCondition class:

public class greaterCondition<T extends Number> extends Condition<T> {
    private T border;

    public  (T border){
        this.border = border;
    }

    @Override
    public boolean condition(T item) {
        return item > border;
    }
}

Here NB does not handle the > operator.

Any bit of help is appreciated!

6
  • 1
    You can't use numeric operators on Number. Commented Jul 24, 2018 at 20:19
  • 1
    For the first problem, you should read What is PECS (Producer Extends Consumer Super)? and "in" vs. "out" variables in the official tutorial Commented Jul 24, 2018 at 20:20
  • Is that me or is your addAll not related to this in any way and could be static or on a different class altogether? You're adding to c as you're iterating through it. This is bound to produce a ConcurrentModificationException. Commented Jul 24, 2018 at 20:26
  • I suspect that addAll should add the elements of c to the array, but it is adding to c itself Commented Jul 24, 2018 at 20:29
  • The way to think of Collection<? extends E> c is "a collection of one particular subclass of E. Of course, you cannot just add a E to it - it has to be that particular subclass of E to be added. And since the actual subclass is not known, no real subclass ever fits. Commented Jul 24, 2018 at 20:30

1 Answer 1

1

Your method is not typesafe, for two reasons:

  1. There is no relationship between E and T; you could pass a collection of some completely unrelated type.
  2. You can add things to a collection of ? extends Whatever, because you don't know what type the collection actually contains (it might be a collection of some other subclass only).

Instead, you should make a non-generic method that accepts a Collection<? super T>, which is guaranteed to be able to hold Ts (since it's a collection of T or a supertype of T).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks SLaks I changed the type-parameter and now I use non-generic method. It is working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.