-
Notifications
You must be signed in to change notification settings - Fork 675
Description
Sometimes, one may want to pass a primitive collection into a method that takes a JCF interface. In cases like this, users must transform the primitive collection into an object collection to proceed.
public static void printAll(List<?> list)
{
System.out.println("list = " + Iterate.makeString(list, ", "));
}
public static void main(String[] args)
{
MutableIntList list = IntLists.mutable.with(1, 2, 3);
printAll(list.collect(Integer::valueOf));
}One option would be to make our primitive collections implement JCF interfaces. Fastutils does this; for example its IntArrayList implements List<Integer>
The downside is that it's very easy to accidentally cause boxing by using the primitive collection inside an enhanced for-loop.
A compromise that I believe would be pragmatic would be to implement a boxing wrappers for primitive collections, and a new method boxed(). If it existed, the example above would become:
printAll(list.boxed());The boxed() method would take O(1) time and space since it returns a wrapper.
To prove the idea, I wrote one wrapper. If we like the idea, we'd need to code generate it for all the primitives, and expand the functionality from just lists to sets and maps.
public class BoxedMutableIntList
extends AbstractMutableList<Integer>
implements MutableList<Integer>, RandomAccess
{
private final MutableIntList delegate;
public BoxedMutableIntList(MutableIntList delegate)
{
this.delegate = Objects.requireNonNull(delegate);
}
@Override
public int size()
{
return this.delegate.size();
}
@Override
public boolean isEmpty()
{
return this.delegate.isEmpty();
}
@Override
public boolean contains(Object o)
{
return o instanceof Integer && this.delegate.contains((Integer) o);
}
@Override
public boolean add(Integer integer)
{
return this.delegate.add(integer.intValue());
}
@Override
public boolean remove(Object o)
{
return o instanceof Integer && this.delegate.remove((Integer) o);
}
@Override
public boolean addAll(int index, Collection<? extends Integer> c)
{
return this.delegate.addAllAtIndex(index, c.stream().mapToInt(Integer::intValue).toArray());
}
@Override
public void clear()
{
this.delegate.clear();
}
@Override
public Integer get(int index)
{
return this.delegate.get(index);
}
@Override
public Integer set(int index, Integer element)
{
return this.delegate.set(index, element.intValue());
}
@Override
public void add(int index, Integer element)
{
this.delegate.addAtIndex(index, element.intValue());
}
@Override
public Integer remove(int index)
{
return this.delegate.removeAtIndex(index);
}
@Override
public int indexOf(Object o)
{
return o instanceof Integer ? this.delegate.indexOf((Integer) o) : -1;
}
@Override
public int lastIndexOf(Object o)
{
return o instanceof Integer ? this.delegate.lastIndexOf((Integer) o) : -1;
}
@Override
public MutableList<Integer> subList(int fromIndex, int toIndex)
{
return this.delegate.subList(fromIndex, toIndex).boxed();
}
}