mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-07 08:16:31 +00:00
Repackage utils
This commit is contained in:
82
src/main/java/com/volmit/iris/util/collection/GBiset.java
Normal file
82
src/main/java/com/volmit/iris/util/collection/GBiset.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.collection;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A Biset
|
||||
*
|
||||
* @param <A> the first object type
|
||||
* @param <B> the second object type
|
||||
* @author cyberpwn
|
||||
*/
|
||||
@SuppressWarnings("hiding")
|
||||
public class GBiset<A, B> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private A a;
|
||||
private B b;
|
||||
|
||||
/**
|
||||
* Create a new Biset
|
||||
*
|
||||
* @param a the first object
|
||||
* @param b the second object
|
||||
*/
|
||||
public GBiset(A a, B b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object of the type A
|
||||
*
|
||||
* @return the first object
|
||||
*/
|
||||
public A getA() {
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the first object
|
||||
*
|
||||
* @param a the first object A
|
||||
*/
|
||||
public void setA(A a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the second object
|
||||
*
|
||||
* @return the second object
|
||||
*/
|
||||
public B getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the second object
|
||||
*
|
||||
*/
|
||||
public void setB(B b) {
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.collection;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Adapts a list of objects into a list of other objects
|
||||
*
|
||||
* @param <FROM> the from object in lists (the item INSIDE the list)
|
||||
* @param <TO> the to object in lists (the item INSIDE the list)
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public abstract class GListAdapter<FROM, TO> {
|
||||
/**
|
||||
* Adapts a list of FROM to a list of TO
|
||||
*
|
||||
* @param from the from list
|
||||
* @return the to list
|
||||
*/
|
||||
public List<TO> adapt(List<FROM> from) {
|
||||
List<TO> adapted = new KList<>();
|
||||
|
||||
for (FROM i : from) {
|
||||
TO t = onAdapt(i);
|
||||
|
||||
if (t != null) {
|
||||
adapted.add(onAdapt(i));
|
||||
}
|
||||
}
|
||||
|
||||
return adapted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts a list object FROM to TO for use with the adapt method
|
||||
*
|
||||
* @param from the from object
|
||||
* @return the to object
|
||||
*/
|
||||
public abstract TO onAdapt(FROM from);
|
||||
}
|
||||
673
src/main/java/com/volmit/iris/util/collection/KList.java
Normal file
673
src/main/java/com/volmit/iris/util/collection/KList.java
Normal file
@@ -0,0 +1,673 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.collection;
|
||||
|
||||
import com.google.common.util.concurrent.AtomicDoubleArray;
|
||||
import com.volmit.iris.util.json.JSONArray;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public class KList<T> extends ArrayList<T> implements List<T> {
|
||||
private static final long serialVersionUID = -2892550695744823337L;
|
||||
|
||||
@SafeVarargs
|
||||
public KList(T... ts) {
|
||||
super();
|
||||
add(ts);
|
||||
}
|
||||
|
||||
public KList() {
|
||||
super();
|
||||
}
|
||||
|
||||
public KList(int cap) {
|
||||
super(cap);
|
||||
}
|
||||
|
||||
public KList(Collection<T> values) {
|
||||
super();
|
||||
add(values);
|
||||
}
|
||||
|
||||
public KList(Enumeration<T> e) {
|
||||
super();
|
||||
add(e);
|
||||
}
|
||||
|
||||
public int indexOfAddIfNeeded(T v) {
|
||||
addIfMissing(v);
|
||||
return indexOf(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the last element
|
||||
*/
|
||||
public KList<T> removeLast() {
|
||||
remove(last());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void addMultiple(T t, int c) {
|
||||
for (int i = 0; i < c; i++) {
|
||||
add(t);
|
||||
}
|
||||
}
|
||||
|
||||
private KList<T> add(Enumeration<T> e) {
|
||||
while (e.hasMoreElements()) {
|
||||
add(e.nextElement());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public KList<T> add(Collection<T> values) {
|
||||
addAll(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Map out of this list where this list becomes the values of the
|
||||
* returned map. You must specify each key for each value in this list. In the
|
||||
* function, returning null will not add the keyval pair.
|
||||
*
|
||||
* @param <K> the inferred key type
|
||||
* @param f the function
|
||||
* @return the new map
|
||||
*/
|
||||
public <K> KMap<K, T> asValues(Function<T, K> f) {
|
||||
KMap<K, T> m = new KMap<K, T>();
|
||||
forEach((i) -> m.putNonNull(f.apply(i), i));
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Map out of this list where this list becomes the keys of the
|
||||
* returned map. You must specify each value for each key in this list. In the
|
||||
* function, returning null will not add the keyval pair.
|
||||
*
|
||||
* @param <V> the inferred value type
|
||||
* @param f the function
|
||||
* @return the new map
|
||||
*/
|
||||
public <V> KMap<T, V> asKeys(Function<T, V> f) {
|
||||
KMap<T, V> m = new KMap<T, V>();
|
||||
forEach((i) -> m.putNonNull(i, f.apply(i)));
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut this list into targetCount sublists
|
||||
*
|
||||
* @param targetCount the target count of sublists
|
||||
* @return the list of sublists
|
||||
*/
|
||||
public KList<KList<T>> divide(int targetCount) {
|
||||
return split(size() / targetCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split this list into a list of sublists with roughly targetSize elements of T
|
||||
* per sublist
|
||||
*
|
||||
* @param targetSize the target size
|
||||
* @return the list of sublists
|
||||
*/
|
||||
public KList<KList<T>> split(int targetSize) {
|
||||
targetSize = targetSize < 1 ? 1 : targetSize;
|
||||
KList<KList<T>> gg = new KList<>();
|
||||
KList<T> b = new KList<>();
|
||||
|
||||
for (T i : this) {
|
||||
if (b.size() >= targetSize) {
|
||||
gg.add(b.copy());
|
||||
b.clear();
|
||||
}
|
||||
|
||||
b.add(i);
|
||||
}
|
||||
|
||||
if (!b.isEmpty()) {
|
||||
gg.add(b);
|
||||
}
|
||||
|
||||
return gg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite this list by checking each value and changing the value (or not).
|
||||
* Return null to remove the element in the function
|
||||
*
|
||||
* @param t the function
|
||||
* @return the same list (not a copy)
|
||||
*/
|
||||
public KList<T> rewrite(Function<T, T> t) {
|
||||
KList<T> m = copy();
|
||||
clear();
|
||||
|
||||
for (T i : m) {
|
||||
addNonNull(t.apply(i));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* To array
|
||||
*
|
||||
* @return the array
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T[] array() {
|
||||
return (T[]) toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a copy of this list
|
||||
*
|
||||
* @return the copy
|
||||
*/
|
||||
public KList<T> copy() {
|
||||
return new KList<T>().add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffle the list
|
||||
*
|
||||
* @return the same list
|
||||
*/
|
||||
public KList<T> shuffle() {
|
||||
Collections.shuffle(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public KList<T> shuffle(Random rng) {
|
||||
Collections.shuffle(this, rng);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the list (based on toString comparison)
|
||||
*
|
||||
* @return the same list
|
||||
*/
|
||||
public KList<T> sort() {
|
||||
Collections.sort(this, (a, b) -> a.toString().compareTo(b.toString()));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse this list
|
||||
*
|
||||
* @return the same list
|
||||
*/
|
||||
public KList<T> reverse() {
|
||||
Collections.reverse(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + toString(", ") + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Tostring with a seperator for each item in the list
|
||||
*
|
||||
* @param split the seperator
|
||||
* @return the string representing this object
|
||||
*/
|
||||
public String toString(String split) {
|
||||
if (isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (size() == 1) {
|
||||
return get(0).toString();
|
||||
}
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
||||
for (String i : toStringList()) {
|
||||
b.append(split).append(i);
|
||||
}
|
||||
|
||||
return b.substring(split.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke tostring on each value in the list into a string list
|
||||
*
|
||||
* @return the string list
|
||||
*/
|
||||
public KList<String> toStringList() {
|
||||
return convert((t) -> t.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the contents of the given list (v) into this list using a converter
|
||||
*
|
||||
* @param <V> the type of the forign list
|
||||
* @param v the forign (given) list
|
||||
* @param converter the converter that converts the forign type into this list type
|
||||
* @return this list (builder)
|
||||
*/
|
||||
public <V> KList<T> addFrom(List<V> v, Function<V, T> converter) {
|
||||
v.forEach((g) -> add(converter.apply(g)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this list into another list type. Such as GList<Integer> to
|
||||
* GList<String>. list.convert((i) -> "" + i);
|
||||
*
|
||||
* @param <V>
|
||||
* @param converter
|
||||
* @return
|
||||
*/
|
||||
public <V> KList<V> convert(Function<T, V> converter) {
|
||||
KList<V> v = new KList<V>();
|
||||
forEach((t) -> v.addNonNull(converter.apply(t)));
|
||||
return v;
|
||||
}
|
||||
|
||||
public KList<T> removeWhere(Predicate<T> t) {
|
||||
for (T i : copy()) {
|
||||
if (t.test(i)) {
|
||||
remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds T to the list, ignores if null
|
||||
*
|
||||
* @param t the value to add
|
||||
* @return the same list
|
||||
*/
|
||||
public KList<T> addNonNull(T t) {
|
||||
if (t != null) {
|
||||
super.add(t);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps the values of index a and b. For example "hello", "world", "!" swap(1,
|
||||
* 2) would change the list to "hello", "!", "world"
|
||||
*
|
||||
* @param a the first index
|
||||
* @param b the second index
|
||||
* @return the same list (builder), not a copy
|
||||
*/
|
||||
public KList<T> swapIndexes(int a, int b) {
|
||||
T aa = remove(a);
|
||||
T bb = get(b);
|
||||
add(a, bb);
|
||||
remove(b);
|
||||
add(b, aa);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a number of elements from the list
|
||||
*
|
||||
* @param t the elements
|
||||
* @return this list
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> remove(T... t) {
|
||||
for (T i : t) {
|
||||
super.remove(i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add another glist's contents to this one (addall builder)
|
||||
*
|
||||
* @param t the list
|
||||
* @return the same list
|
||||
*/
|
||||
public KList<T> add(KList<T> t) {
|
||||
super.addAll(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a number of values to this list
|
||||
*
|
||||
* @param t the list
|
||||
* @return this list
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> add(T... t) {
|
||||
for (T i : t) {
|
||||
super.add(i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this list has an index at the given index
|
||||
*
|
||||
* @param index the given index
|
||||
* @return true if size > index
|
||||
*/
|
||||
public boolean hasIndex(int index) {
|
||||
return size() > index && index >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last index of this list (size - 1)
|
||||
*
|
||||
* @return the last index of this list
|
||||
*/
|
||||
public int last() {
|
||||
return size() - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deduplicate this list by converting to linked hash set and back
|
||||
*
|
||||
* @return the deduplicated list
|
||||
*/
|
||||
public KList<T> dedupe() {
|
||||
LinkedHashSet<T> lhs = new LinkedHashSet<T>(this);
|
||||
return qclear().add(lhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear this list (and return it)
|
||||
*
|
||||
* @return the same list
|
||||
*/
|
||||
public KList<T> qclear() {
|
||||
super.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply !isEmpty()
|
||||
*
|
||||
* @return true if this list has 1 or more element(s)
|
||||
*/
|
||||
public boolean hasElements() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply !isEmpty()
|
||||
*
|
||||
* @return true if this list has 1 or more element(s)
|
||||
*/
|
||||
public boolean isNotEmpty() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the first item off this list and return it
|
||||
*
|
||||
* @return the popped off item or null if the list is empty
|
||||
*/
|
||||
public T pop() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return remove(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the last item off this list and return it
|
||||
*
|
||||
* @return the popped off item or null if the list is empty
|
||||
*/
|
||||
public T popLast() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return remove(last());
|
||||
}
|
||||
|
||||
public T popRandom() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (size() == 1) {
|
||||
return pop();
|
||||
}
|
||||
|
||||
return remove(M.irand(0, last()));
|
||||
}
|
||||
|
||||
public static KList<String> fromJSONAny(JSONArray oo) {
|
||||
KList<String> s = new KList<String>();
|
||||
|
||||
for (int i = 0; i < oo.length(); i++) {
|
||||
s.add(oo.get(i).toString());
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public KList<T> sub(int f, int t) {
|
||||
KList<T> g = new KList<>();
|
||||
|
||||
for (int i = f; i < M.min(size(), t); i++) {
|
||||
g.add(get(i));
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
public JSONArray toJSONStringArray() {
|
||||
JSONArray j = new JSONArray();
|
||||
|
||||
for (Object i : this) {
|
||||
j.put(i.toString());
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
public static KList<String> asStringList(List<?> oo) {
|
||||
KList<String> s = new KList<String>();
|
||||
|
||||
for (Object i : oo) {
|
||||
s.add(i.toString());
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(Object[] values) {
|
||||
for (Object i : values) {
|
||||
add((T) i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(int[] values) {
|
||||
for (Object i : values) {
|
||||
add((T) i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(double[] values) {
|
||||
for (Object i : values) {
|
||||
add((T) i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(AtomicDoubleArray values) {
|
||||
for (int i = 0; i < values.length(); i++) {
|
||||
add((T) ((Object) values.get(i)));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(float[] values) {
|
||||
for (Object i : values) {
|
||||
add((T) i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(byte[] values) {
|
||||
for (Object i : values) {
|
||||
add((T) i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(short[] values) {
|
||||
for (Object i : values) {
|
||||
add((T) i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(long[] values) {
|
||||
for (Object i : values) {
|
||||
add((T) i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KList<T> forceAdd(boolean[] values) {
|
||||
for (Object i : values) {
|
||||
add((T) i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public T middleValue() {
|
||||
return get(middleIndex());
|
||||
}
|
||||
|
||||
private int middleIndex() {
|
||||
return size() % 2 == 0 ? (size() / 2) : ((size() / 2) + 1);
|
||||
}
|
||||
|
||||
public T getRandom() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (size() == 1) {
|
||||
return get(0);
|
||||
}
|
||||
|
||||
return get(M.irand(0, last()));
|
||||
}
|
||||
|
||||
public T getRandom(RNG rng) {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (size() == 1) {
|
||||
return get(0);
|
||||
}
|
||||
|
||||
return get(rng.i(0, last()));
|
||||
}
|
||||
|
||||
public KList<T> qdel(T t) {
|
||||
remove(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
public KList<T> qadd(T t) {
|
||||
add(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
public KList<T> qaddIfMissing(T t) {
|
||||
addIfMissing(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
public KList<T> removeDuplicates() {
|
||||
KSet<T> v = new KSet<>();
|
||||
v.addAll(this);
|
||||
KList<T> m = new KList<>();
|
||||
m.addAll(v);
|
||||
return m;
|
||||
}
|
||||
|
||||
public boolean addIfMissing(T t) {
|
||||
if (!contains(t)) {
|
||||
add(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addAllIfMissing(KList<T> t) {
|
||||
for (T i : t) {
|
||||
if (!contains(i)) {
|
||||
add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public KList<T> shuffleCopy(Random rng) {
|
||||
KList<T> t = copy();
|
||||
t.shuffle(rng);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
381
src/main/java/com/volmit/iris/util/collection/KMap.java
Normal file
381
src/main/java/com/volmit/iris/util/collection/KMap.java
Normal file
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.collection;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.function.Consumer2;
|
||||
import com.volmit.iris.util.function.Consumer3;
|
||||
import com.volmit.iris.util.scheduling.Queue;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public class KMap<K, V> extends ConcurrentHashMap<K, V> {
|
||||
private static final long serialVersionUID = 7288942695300448163L;
|
||||
|
||||
public KMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
public KMap(Map<K, V> gMap) {
|
||||
this();
|
||||
put(gMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a value into a map-value-list based on the key such that if GMap<K,
|
||||
* GList<S>> where V is GList<S>
|
||||
*
|
||||
* @param <S> the list type in the value type
|
||||
* @param k the key to look for
|
||||
* @param vs the values to put into the list of the given key
|
||||
* @return the same list (builder)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S> KMap<K, V> putValueList(K k, S... vs) {
|
||||
try {
|
||||
KMap<K, KList<S>> s = (KMap<K, KList<S>>) this;
|
||||
|
||||
if (!s.containsKey(k)) {
|
||||
s.put(k, new KList<S>());
|
||||
}
|
||||
|
||||
s.get(k).add(vs);
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sorted list of keys from this map, based on the sorting order of
|
||||
* the values.
|
||||
*
|
||||
* @return the value-sorted key list
|
||||
*/
|
||||
public KList<K> sortK() {
|
||||
KList<K> k = new KList<K>();
|
||||
KList<V> v = v();
|
||||
|
||||
Collections.sort(v, new Comparator<V>() {
|
||||
@Override
|
||||
public int compare(V v, V t1) {
|
||||
return v.toString().compareTo(t1.toString());
|
||||
}
|
||||
});
|
||||
|
||||
for (V i : v) {
|
||||
for (K j : k()) {
|
||||
if (get(j).equals(i)) {
|
||||
k.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k.dedupe();
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sorted list of keys from this map, based on the sorting order of
|
||||
* the values. Sorting is based on numerical values
|
||||
*
|
||||
* @return the value-sorted key list
|
||||
*/
|
||||
public KList<K> sortKNumber() {
|
||||
KList<K> k = new KList<K>();
|
||||
KList<V> v = v();
|
||||
|
||||
Collections.sort(v, new Comparator<V>() {
|
||||
@Override
|
||||
public int compare(V v, V t1) {
|
||||
Number n1 = (Number) v;
|
||||
Number n2 = (Number) t1;
|
||||
|
||||
return (int) ((n1.doubleValue() - n2.doubleValue()) * 1000);
|
||||
}
|
||||
});
|
||||
|
||||
for (V i : v) {
|
||||
for (K j : k()) {
|
||||
if (get(j).equals(i)) {
|
||||
k.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k.dedupe();
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put another map's values into this map
|
||||
*
|
||||
* @param m the map to insert
|
||||
* @return this map (builder)
|
||||
*/
|
||||
public KMap<K, V> put(Map<K, V> m) {
|
||||
putAll(m);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a copy of this map
|
||||
*
|
||||
* @return the copied map
|
||||
*/
|
||||
public KMap<K, V> copy() {
|
||||
return new KMap<K, V>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through each keyvalue set (copy of it) with the map parameter
|
||||
*
|
||||
* @param f the function
|
||||
* @return the same gmap
|
||||
*/
|
||||
public KMap<K, V> rewrite(Consumer3<K, V, KMap<K, V>> f) {
|
||||
KMap<K, V> m = copy();
|
||||
|
||||
for (K i : m.k()) {
|
||||
f.accept(i, get(i), this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through each keyvalue set (copy of it)
|
||||
*
|
||||
* @param f the function
|
||||
* @return the same gmap
|
||||
*/
|
||||
public KMap<K, V> each(Consumer2<K, V> f) {
|
||||
for (K i : k()) {
|
||||
f.accept(i, get(i));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip the hashmap and flatten the value list even if there are multiple keys
|
||||
*
|
||||
* @return the flipped and flattened hashmap
|
||||
*/
|
||||
public KMap<V, K> flipFlatten() {
|
||||
KMap<V, KList<K>> f = flip();
|
||||
KMap<V, K> m = new KMap<>();
|
||||
|
||||
for (V i : f.k()) {
|
||||
m.putNonNull(i, m.isEmpty() ? null : m.get(0));
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip the hashmap so keys are now list-keys in the value position
|
||||
*
|
||||
* @return the flipped hashmap
|
||||
*/
|
||||
public KMap<V, KList<K>> flip() {
|
||||
KMap<V, KList<K>> flipped = new KMap<V, KList<K>>();
|
||||
|
||||
for (K i : keySet()) {
|
||||
if (i == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!flipped.containsKey(get(i))) {
|
||||
flipped.put(get(i), new KList<K>());
|
||||
}
|
||||
|
||||
flipped.get(get(i)).add(i);
|
||||
}
|
||||
|
||||
return flipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort values based on the keys sorting order
|
||||
*
|
||||
* @return the values (sorted)
|
||||
*/
|
||||
public KList<V> sortV() {
|
||||
KList<V> v = new KList<V>();
|
||||
KList<K> k = k();
|
||||
|
||||
Collections.sort(k, new Comparator<K>() {
|
||||
@Override
|
||||
public int compare(K v, K t1) {
|
||||
return v.toString().compareTo(t1.toString());
|
||||
}
|
||||
});
|
||||
|
||||
for (K i : k) {
|
||||
for (V j : v()) {
|
||||
if (get(i).equals(j)) {
|
||||
v.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v.dedupe();
|
||||
return v;
|
||||
}
|
||||
|
||||
public KList<V> sortVNoDedupe() {
|
||||
KList<V> v = new KList<V>();
|
||||
KList<K> k = k();
|
||||
|
||||
Collections.sort(k, new Comparator<K>() {
|
||||
@Override
|
||||
public int compare(K v, K t1) {
|
||||
return v.toString().compareTo(t1.toString());
|
||||
}
|
||||
});
|
||||
|
||||
for (K i : k) {
|
||||
for (V j : v()) {
|
||||
if (get(i).equals(j)) {
|
||||
v.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a copy of this maps keys
|
||||
*
|
||||
* @return the keys
|
||||
*/
|
||||
public KList<K> k() {
|
||||
KList<K> k = new KList<K>();
|
||||
Enumeration<K> kk = keys();
|
||||
|
||||
while (kk.hasMoreElements()) {
|
||||
K kkk = kk.nextElement();
|
||||
k.add(kkk);
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a copy of this maps values
|
||||
*
|
||||
* @return the values
|
||||
*/
|
||||
public KList<V> v() {
|
||||
return new KList<V>(values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Still works as it normally should except it returns itself (builder)
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value (single only supported)
|
||||
* @return
|
||||
*/
|
||||
public KMap<K, V> qput(K key, V value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Works just like put, except it wont put anything unless the key and value are
|
||||
* nonnull
|
||||
*
|
||||
* @param key the nonnull key
|
||||
* @param value the nonnull value
|
||||
* @return the same map
|
||||
*/
|
||||
public KMap<K, V> putNonNull(K key, V value) {
|
||||
if (key != null || value != null) {
|
||||
put(key, value);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public V putThen(K key, V valueIfKeyNotPresent) {
|
||||
if (!containsKey(key)) {
|
||||
put(key, valueIfKeyNotPresent);
|
||||
}
|
||||
|
||||
return get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear this map and return it
|
||||
*
|
||||
* @return the cleared map
|
||||
*/
|
||||
public KMap<K, V> qclear() {
|
||||
super.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this map to keypairs
|
||||
*
|
||||
* @return the keypair list
|
||||
*/
|
||||
public KList<KeyPair<K, V>> keypair() {
|
||||
KList<KeyPair<K, V>> g = new KList<>();
|
||||
each((k, v) -> g.add(new KeyPair<K, V>(k, v)));
|
||||
return g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a keypair queue
|
||||
*
|
||||
* @return the queue
|
||||
*/
|
||||
public Queue<KeyPair<K, V>> enqueue() {
|
||||
return Queue.create(keypair());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a key queue
|
||||
*
|
||||
* @return the queue
|
||||
*/
|
||||
public Queue<K> enqueueKeys() {
|
||||
return Queue.create(k());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a value queue
|
||||
*
|
||||
* @return the queue
|
||||
*/
|
||||
public Queue<V> enqueueValues() {
|
||||
return Queue.create(v());
|
||||
}
|
||||
}
|
||||
46
src/main/java/com/volmit/iris/util/collection/KSet.java
Normal file
46
src/main/java/com/volmit/iris/util/collection/KSet.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.collection;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class KSet<T> extends HashSet<T> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public KSet() {
|
||||
super();
|
||||
}
|
||||
|
||||
public KSet(Collection<? extends T> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
public KSet(int initialCapacity, float loadFactor) {
|
||||
super(initialCapacity, loadFactor);
|
||||
}
|
||||
|
||||
public KSet(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
}
|
||||
|
||||
public KSet<T> copy() {
|
||||
return new KSet<T>(this);
|
||||
}
|
||||
}
|
||||
59
src/main/java/com/volmit/iris/util/collection/KeyPair.java
Normal file
59
src/main/java/com/volmit/iris/util/collection/KeyPair.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.collection;
|
||||
|
||||
/**
|
||||
* Represents a keypair
|
||||
*
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @author cyberpwn
|
||||
*/
|
||||
@SuppressWarnings("hiding")
|
||||
public class KeyPair<K, V> {
|
||||
private K k;
|
||||
private V v;
|
||||
|
||||
/**
|
||||
* Create a keypair
|
||||
*
|
||||
* @param k the key
|
||||
* @param v the value
|
||||
*/
|
||||
public KeyPair(K k, V v) {
|
||||
this.k = k;
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
public K getK() {
|
||||
return k;
|
||||
}
|
||||
|
||||
public void setK(K k) {
|
||||
this.k = k;
|
||||
}
|
||||
|
||||
public V getV() {
|
||||
return v;
|
||||
}
|
||||
|
||||
public void setV(V v) {
|
||||
this.v = v;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user