How do I refactor this loop?

You can’t shouldn’t (*) do this in a single method. Item[] and List<Item> are unrelated types.

You should make one of the overloads call the other: either something(Item... items) calls something(List<Item>), or something(List<Item>) calls something(Item... items).

Of the two options, it is better for the array overload to call the list overload:

public void something(Item... items) {
  something(Arrays.asList(item));
}

This is cheap, because it doesn’t copy the array, but rather wraps it: creating the List is O(1).

If you were to invoke the array overload from the list overload:

public void something(List<Item> items) {
  something(items.toArray(new Item[0]));
}

This would be more expensive, since the toArray call has to create and populate an array: it is an O(n) operation, where n is the size of the list. However, it has the slight advantage that something would not be able to replace the contents of the List, since any updates to the array are simply discarded after execution.


(*) You can, but it would be really gross, and not type-safe, as you’d have to accept an Object parameter, as there is no other common super type of List<Item> and Item[]; and you’d still end up having to repeat the loops for the two types; and you’d have to handle the possibility of a completely unrelated type being passed in (at runtime):

public void something(Object obj) {
  if (obj instanceof List) {
    for (Object element : (List<?>) obj) {
      Item item = (Item) element;  // Potential ClassCastException.
      doStuff();
    }
  } else if (obj instanceof Item[]) {
    for (Item item : (Item[]) obj) {
      doStuff();
    }
  } else {
    throw new IllegalArgumentException();
  }
}

What a mess. Thank the maker for overloads.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)