0

I have a method that takes in a Collection of type T as a parameter and returns a Collection of type Integer. In this specific instance, I'm trying to return an ArrayList (am I wrong to do that? I figured since an ArrayList inherits from a Collection, that should be okay).

@Test public void test() {
  Collection<Integer> list = new ArrayList<Integer>();
  list.add(2);
  list.add(8);
  list.add(7);
  list.add(3);
  list.add(4);
  Comparison comp = new Comparison();
  int low = 1;
  int high = 5;
  ArrayList<Integer> actual = SampleClass.<Integer>range(list, low, high, comp);
  ArrayList<Integer> expected = new ArrayList<Integer>();
  expected.add(2);
  expected.add(3);
  expected.add(4);
  Assert.assertEquals(expected, actual);
}

What am I doing wrong here?

EDIT:

As requested, here is the discussed method:

public static <T> Collection<T> range(Collection<T> coll, T low, T high,
                                     Comparator<T> comp) {
  if (coll == null || comp == null) {
     throw new IllegalArgumentException("No Collection or Comparator.");
  }
  if (coll.size() == 0) {
     throw new NoSuchElementException("Collection is empty.");
  }
  ArrayList<T> al = new ArrayList<T>();
  for (T t : coll) {
     if (comp.compare(t, low) >= 0 && comp.compare(t, high) <= 0) {
        al.add(t);
     }
  }
  return al;
}
Jeriel Ng
  • 191
  • 1
  • 4
  • 14
  • What is the error? Could you paste the code for SampleClass.range. – uncaught_exception Feb 09 '16 at 17:36
  • It gives me an incompatible types error: incompatible types: Collection cannot be converted to ArrayList – Jeriel Ng Feb 09 '16 at 17:43
  • 1
    `ArrayList actual = new ArrayList<>(SampleClass.range(list, low, high, comp));`? – Andy Turner Feb 09 '16 at 17:45
  • That seemed to work. Thanks! Could you explain the syntax behind that? – Jeriel Ng Feb 09 '16 at 17:53
  • @Alvarno Collection cannot be assigned to ArrayList. You would need to add a cast or do as Andy suggested. That said could you show the method that takes Collection and returns Collection? – uncaught_exception Feb 09 '16 at 17:53
  • @Alvarno ArrayList has a constructor ArrayList(Collection extends E> c). https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(java.util.Collection) that Andy is using. You could also add a cast actual = (ArrayList)SampleClass.... although with this you must be sure your method actually returns an ArrayList. I prefer Andy's way. – uncaught_exception Feb 09 '16 at 17:56

1 Answers1

0

The comment from Andy Turner suggests copying the returned collection into an ArrayList, which can then be compared to another ArrayList using equals(). This makes the code compile and presumably lets the test pass.

The fact that the potential solutions include casting the result or copying it into a container of a different type raise some questions about what's actually going on here.

Copying the result Collection into a List makes some possibly unwarranted assumptions about the range() method. It's declared to return a Collection. If your test is modified to copy the result to a List and compares it to an expected result, also a List, the test constrains the range() implementation to produce its results in a particular order. If order is significant, perhaps range() should be modified to consume and return List instead of Collection.

But what if order doesn't matter? If the returned collection contained [4, 3, 2] instead of [2, 3, 4], would that be acceptable? If so, then you'll need to compare the actual and expected results in an order-independent fashion. For techniques to do that, see this question:

Is there a way to check if two Collections contain the same elements, independent of order?

Community
  • 1
  • 1
Stuart Marks
  • 127,867
  • 37
  • 205
  • 259