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!

Zsu.Jom
  • 3
  • 2
  • 1
    You can't use numeric operators on `Number`. – shmosel Jul 24 '18 at 20:19
  • 1
    For the first problem, you should read [*What is PECS (Producer Extends Consumer Super)?*](https://stackoverflow.com/q/2723397/2891664) and ["in" vs. "out" variables in the official tutorial](https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html) – Radiodef Jul 24 '18 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`. –  Jul 24 '18 at 20:26
  • I suspect that `addAll` should add the elements of `c` to the `array`, but it is adding to `c` itself – user85421 Jul 24 '18 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. –  Jul 24 '18 at 20:30
  • Thanks Arkadiy and Carlos I have combined your advices and I have found the solution. – Zsu.Jom Jul 24 '18 at 21:20

1 Answers1

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).

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964