
monniasza.collects.Collects Maven / Gradle / Ivy
/**
*
*/
package monniasza.collects;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import javax.swing.DefaultListModel;
import javax.swing.ListModel;
import javax.swing.event.ListDataListener;
import com.google.common.collect.Iterators;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.SetMultimap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import mmb.NN;
import mmb.Nil;
import mmb.engine.item.ItemEntry;
import mmb.engine.recipe.RecipeOutput;
import monniasza.collects.grid.Grid;
import monniasza.collects.selfset.SelfSet;
/**
* A set of operations on collections used in MultiMachineBuilder
* @author oskar
*/
public class Collects {
private Collects() {}
//Iterators
/**
* Down-casts the iterator
* @param type of the output iterator
* @param iter iterator
* @return downcasted iterator
*/
@SuppressWarnings("unchecked")
@NN public static Iterator downcastIterator(Iterator extends T> iter) {
return (Iterator) iter;
}
/**
* Converts an {@link Iterator} to an {@link Iterable}
* @param type of iterator
* @param iter iterator to be converted
* @return wrapped iterator object
*/
@NN public static Iterable iter(Iterator iter){
return () -> iter;
}
/**
* Converts an {@link Enumeration} to an {@link Iterable}
* @param type of enumeration
* @param iter enumeration to be converted
* @return wrapped enumeration object
*/
@SuppressWarnings("null")
public static Iterable iter(Enumeration iter) {
return iter::asIterator;
}
//List models
/**
* Wraps the {@link ListModel} in a {@link List}, to allow Java Collections Framework operations to be used
* @param
* @param list the ListModel to be wrapped
* @return the wrapped list
*/
@NN public static List fromListModel(ListModel list){
return new AbstractList<>() {
@Override public T get(int index) {
return list.getElementAt(index);
}
@Override public int size() {
return list.getSize();
}
};
}
/**
* Wraps the list to a list model
* @param type of the list
* @param list list to wrap
* @return a list model
* @apiNote The list model does not support listeners
*/
@NN public static ListModel toListModel(List list){
return new ListModel<>() {
@Override
public void addListDataListener(@Nil ListDataListener l) {
throw new UnsupportedOperationException("ListModel from List does not support listeners");
}
@Override
public T getElementAt(int index) {
return list.get(index);
}
@Override
public int getSize() {
return list.size();
}
@Override
public void removeListDataListener(@Nil ListDataListener l) {
throw new UnsupportedOperationException("ListModel from List oes not support listeners");
}
};
}
/**
* Wraps a list model
* @param type of the list model
* @param list list model
* @return a list wrapper
*/
@NN public static List toWritableList(DefaultListModel list){
return new AbstractList<>() {
@Override
public T get(int index) {
return list.get(index);
}
@Override
public int size() {
return list.getSize();
}
@Override
public void add(int index, @Nil T element) {
list.add(index, element);
}
@Override
public boolean add(@Nil T e) {
list.addElement(e);
return true;
}
@Override
public T remove(int index) {
return list.remove(index);
}
@Override
public T set(int index, @SuppressWarnings("null") @Nil T e) {
return list.set(index, e);
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public boolean contains(@Nil Object o) {
return list.contains(list);
}
@SuppressWarnings("null")
@Override
public @NN Iterator iterator() {
return list.elements().asIterator();
}
@SuppressWarnings("null")
@Override
public Object @NN [] toArray() {
return list.toArray();
}
@Override
public U @NN [] toArray(U[] a) {
list.copyInto(a);
return a;
}
@Override
public boolean remove(@Nil Object o) {
return list.removeElement(o);
}
@Override
public boolean containsAll(Collection> c) {
for(Object e: c) {
if(!list.contains(e)) return false;
}
return true;
}
@Override
public boolean addAll(Collection extends T> c) {
list.addAll(c);
return true;
}
@Override
public boolean addAll(int index, Collection extends T> c) {
list.addAll(index, c);
return true;
}
@Override
public boolean removeAll(Collection> c) {
boolean result = false;
for(Object e: c) {
result |= list.removeElement(e);
}
return result;
}
@Override
public boolean retainAll(Collection> c) {
List copy = new ArrayList<>(this);
boolean result = copy.retainAll(c);
list.addAll(copy);
return result;
}
@Override
public void clear() {
list.removeAllElements();
}
@Override
public int indexOf(@Nil Object o) {
return list.indexOf(o);
}
@Override
public int lastIndexOf(@Nil Object o) {
return list.lastIndexOf(o);
}
};
}
@NN public static DefaultListModel newListModel(Collection extends T> list){
DefaultListModel model = new DefaultListModel<>();
model.addAll(list);
return model;
}
//Self-sets
/**
* @param type of keys of the output set
* @param type of values of the output set
* @param set self-set to wrap
* @return an unmodifiable wrapper around the self-set
*/
@NN public static SelfSet unmodifiableSelfSet(SelfSet extends K, ? extends V> set){
return new SelfSet<>() {
@Override
public boolean add(@Nil V e) {
return false;
}
@Override
public boolean addAll(Collection extends V> c) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
@Override
public boolean containsAll(Collection> c) {
return set.containsAll(c);
}
@Override
public boolean isEmpty() {
return set.isEmpty();
}
@Override
public Iterator iterator() {
return downcastIterator(set.iterator());
}
@Override
public boolean removeAll(Collection> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(Collection> c) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
return set.size();
}
@Override
public Object[] toArray() {
return set.toArray();
}
@Override
public T[] toArray(T[] a) {
return set.toArray(a);
}
@Override
public Set keys() {
return Collections.unmodifiableSet(set.keys());
}
@Override
public Set values() {
return Collections.unmodifiableSet(set.values());
}
@Override
public V get(@Nil Object key) {
return set.get(key);
}
@SuppressWarnings("unchecked") //cast is required to accept a supertype, it will never fail
@Override
public V getOrDefault(@Nil Object key, V defalt) {
return ((SelfSet)set).getOrDefault(key, defalt);
}
@Override
public boolean removeKey(K key) {
throw new UnsupportedOperationException();
}
@Override
public boolean containsKey(@Nil Object key) {
return set.containsKey(key);
}
@Override
public boolean test(@Nil Object o) {
return set.test(o);
}
@Override
public K id(Object value) {
return set.id(value);
}
@Override
public boolean nullable() {
return set.nullable();
}
@SuppressWarnings("unchecked")
@Override
public Class type() {
return (Class) set.type();
}
};
}
//Lists
/**
* Adds the second input to the first one in-place
* @param type of elements
* @param list list to add to
* @param collect elements to be added
* @return first input
*/
@NN public static List inplaceAddLists(List list, Collection extends T> collect){
list.addAll(collect);
return list;
}
/**
* Adds two inputs out of place
* @param
* @param a first half of the list
* @param b second half of the list
* @param supplier creates lists
* @return a new list
*/
@NN public static List ooplaceAddLists(Collection extends T> a, Collection extends T> b, Supplier> supplier){
List list0 = supplier.get();
list0.addAll(a);
list0.addAll(b);
return list0;
}
/**
* Creates an out-of-place list added
* @param type of values
* @param supplier creates lists
* @return a list addition function
*/
@NN public static BiFunction<@NN Collection extends T>, @NN Collection extends T>, List> ooplaceListAdder(Supplier> supplier){
return (a, b) -> ooplaceAddLists(a, b, supplier);
}
//Multimaps
/**
* Creates an empty multimap
* @param type of keys
* @param type of values
* @return an empty, immutable multimap
*/
@SuppressWarnings("unchecked")
@NN public static SetMultimap emptyMultimap(){
return (SetMultimap) emptyMultiMap;
}
@NN private static final SetMultimap, ?> emptyMultiMap = new EmptySetMultimap();
/**
* Creates an empty multiset
* @param type of values
* @return an empty, immutable multiset
*/
@SuppressWarnings("unchecked")
@NN public static Multiset emptyMultiset(){
return (Multiset) emptyMultiSet;
}
@NN private static final Multiset> emptyMultiSet = new EmptyMultiSet();
//Maps
/**
* Creates an int-to-any map from a stream
* @param type of values
* @param type of maps
* @param mapsup creates maps
* @return an int/obj map collector
*/
@NN public static > Collector, Object2IntMap, M> collectToIntMap(Supplier mapsup){
return new IntMapCollector<>(mapsup);
}
/**
* Adds the second input to the first input
* @param type of values
* @param type of the modified map
* @param list map to be modified
* @param collect map to be added to the first input
* @return first input
*/
@NN public static > M inplaceAddIntMaps(M list, Object2IntMap extends T> collect){
list.putAll(collect);
return list;
}
//Grids
/**
* Prevents changes to a grid
* @param grid grid to prevent changes to
* @return an unmodifiable view of the input grid
*/
public static Grid unmodifiableGrid(Grid grid) {
return new Grid<>() {
@Override
public void set(int x, int y, T data) {
throw new UnsupportedOperationException();
}
@Override
public T get(int x, int y) {
return grid.get(x, y);
}
@Override
public int width() {
return grid.width();
}
@Override
public int height() {
return grid.height();
}
@SuppressWarnings("null")
@Override
public Iterator iterator() {
return Iterators.unmodifiableIterator(grid.iterator());
}
};
}
/**
* Creates a dynamically-mapped view of a grid
* @param type of the input grid
* @param type of the output grid
* @param forward forward mapper
* @param backward backward mapper
* @param grid input grid
* @return a transformed view of the grid. The view is backed by the grid, so any changes made to the original are reflected in the view and vice versa
*/
public static Grid mapGrid(Function super Tin, ? extends Tout> forward, @Nil Function super Tout, ? extends Tin> backward, Grid grid){
return new Grid<>() {
@Override
public void set(int x, int y, Tout data) {
if(backward == null) throw new UnsupportedOperationException("no backwards function");
grid.set(x, y, backward.apply(data));
}
@Override
public Tout get(int x, int y) {
return forward.apply(grid.get(x, y));
}
@Override
public int width() {
return grid.width();
}
@Override
public int height() {
return grid.height();
}
@Override
public Iterator iterator() {
Iterator iter = grid.iterator();
return new Iterator<>() {
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public Tout next() {
return forward.apply(iter.next());
}
@Override
public void remove() {
iter.remove();
}
};
}
};
}
//Iteration
/**
* Gets the first item using iteration
* @param c collection to get items from
* @return the first item
* @throws NoSuchElementException when there is no requested item
*/
public static T first(Iterable c) {
return c.iterator().next();
}
//All/any boolean operations
/**
* Checks if all values meet a predicate
* @param type of values
* @param collection collection to test
* @param predicate condition
* @return do all items meet a criterion?
*/
public static boolean isAll(Iterable extends T> collection, Predicate predicate) {
for(T value: collection)
if(!predicate.test(value)) return false;
return true;
}
/**
* Checks if any value meets a predicate
* @param type of values
* @param collection collection to test
* @param predicate condition
* @return does any items meet a criterion?
*/
public static boolean isAny(Iterable extends T> collection, Predicate predicate) {
for(T value: collection)
if(predicate.test(value)) return true;
return false;
}
}
class IntMapCollector> implements Collector, Object2IntMap, M>{
@NN private final Supplier mapsup;
public IntMapCollector(Supplier mapsup) {
this.mapsup = mapsup;
}
@Override
public Supplier> supplier() {
return Object2IntOpenHashMap::new;
}
@Override
public BiConsumer, Object2IntMap.Entry> accumulator() {
return (map, entry) -> map.put(entry.getKey(), entry.getIntValue());
}
@Override
public BinaryOperator> combiner() {
return Collects::inplaceAddIntMaps;
}
@SuppressWarnings("null")
@Override
public Function, M> finisher() {
return map -> {
M result = mapsup.get();
return Collects.inplaceAddIntMaps(result, map);
};
}
@Override
public Set characteristics() {
return Set.of(Characteristics.UNORDERED);
}
}
class EmptyMultiSet implements Multiset
© 2015 - 2025 Weber Informatics LLC | Privacy Policy