org.libj.util.TransCollection Maven / Gradle / Ivy
Show all versions of util Show documentation
/* Copyright (c) 2017 LibJ
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of The MIT License (MIT) along with this
* program. If not, see .
*/
package org.libj.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Function;
/**
* An implementation of the Collection interface that transforms the elements of
* the supplied source Collection based on {@code sourceToTarget} and
* {@code targetToSource} lambda functions.
*
* @param Type of source Collection.
* @param Type of target Collection.
* @see Collection
*/
public class TransCollection extends DelegateCollection {
protected final Function sourceToTarget;
protected final Function targetToSource;
/**
* Creates a new {@link TransCollection} with the specified source Collection,
* and functions defining the translation of objects types {@code S -> T} and
* {@code T -> S}.
*
* If {@code sourceToTarget} is null, all methods that require a translation
* of {@code S -> T} will throw a {@link UnsupportedOperationException}.
*
* If {@code targetToSource} is null, all methods that require a translation
* of {@code T -> S} will throw a {@link UnsupportedOperationException}.
*
* @param source The source Collection of type {@code }.
* @param sourceToTarget The {@link Function} defining the translation from
* {@code S -> T}.
* @param targetToSource The {@link Function} defining the translation from
* {@code T -> S}.
* @throws NullPointerException If {@code source} is null.
*/
public TransCollection(final Collection source, final Function sourceToTarget, final Function targetToSource) {
super.target = Objects.requireNonNull(source);
this.sourceToTarget = sourceToTarget;
this.targetToSource = targetToSource;
}
@Override
public boolean contains(final Object o) {
if (sourceToTarget == null)
throw new UnsupportedOperationException();
final Iterator iterator = target.iterator();
if (o != null) {
while (iterator.hasNext())
if (o.equals(sourceToTarget.apply(iterator.next())))
return true;
}
else {
while (iterator.hasNext())
if (iterator.next() == null)
return true;
}
return false;
}
@Override
public Iterator iterator() {
final Iterator iterator = target.iterator();
return new Iterator() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public T next() {
if (sourceToTarget == null)
throw new UnsupportedOperationException();
return sourceToTarget.apply(iterator.next());
}
@Override
public void remove() {
iterator.remove();
}
};
}
@Override
public Object[] toArray() {
if (sourceToTarget == null)
throw new UnsupportedOperationException();
final Object[] array = new Object[size()];
final Iterator iterator = target.iterator();
for (int i = 0; i < size(); ++i)
array[i] = sourceToTarget.apply(iterator.next());
return array;
}
@Override
@SuppressWarnings("unchecked")
public E[] toArray(final E[] a) {
if (sourceToTarget == null)
throw new UnsupportedOperationException();
final Iterator iterator = target.iterator();
for (int i = 0; i < size(); ++i)
a[i] = (E)sourceToTarget.apply(iterator.next());
return a;
}
@Override
public boolean add(final T e) {
if (targetToSource == null)
throw new UnsupportedOperationException();
return target.add(targetToSource.apply(e));
}
@Override
public boolean remove(final Object o) {
if (sourceToTarget == null)
throw new UnsupportedOperationException();
final Iterator iterator = target.iterator();
while (iterator.hasNext()) {
final S e = iterator.next();
if (o != null ? o.equals(sourceToTarget.apply(e)) : sourceToTarget.apply(e) == null) {
iterator.remove();
return true;
}
}
return false;
}
@Override
@SuppressWarnings("unlikely-arg-type")
public boolean containsAll(final Collection> c) {
if (c.size() == 0)
return true;
for (final Object e : c)
if (contains(e))
return true;
return false;
}
@Override
public boolean addAll(final Collection extends T> c) {
boolean changed = false;
for (final T e : c)
changed |= add(e);
return changed;
}
@Override
@SuppressWarnings("unlikely-arg-type")
public boolean removeAll(final Collection> c) {
boolean changed = false;
for (final Object e : c)
changed |= remove(e);
return changed;
}
@Override
@SuppressWarnings("unlikely-arg-type")
public boolean retainAll(final Collection> c) {
boolean changed = false;
final Iterator iterator = target.iterator();
while (iterator.hasNext()) {
final S e = iterator.next();
if (!c.contains(e == null ? null : sourceToTarget.apply(e))) {
iterator.remove();
changed = true;
}
}
return changed;
}
}