/* * This file is licensed under the MIT License, part of Roughly Enough Items. * Copyright (c) 2018, 2019, 2020 shedaniel * * 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. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package me.shedaniel.rei.utils; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.collect.UnmodifiableIterator; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import me.shedaniel.rei.api.EntryStack; import me.shedaniel.rei.api.entry.EntryStacks; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.util.Mth; import java.util.*; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.function.ToIntFunction; import java.util.stream.Collectors; import java.util.stream.Stream; public class CollectionUtils { public static List getOrPutEmptyList(Map> map, A key) { List b = map.get(key); if (b != null) return b; map.put(key, Lists.newArrayList()); return map.get(key); } public static T findFirstOrNullEquals(List list, T obj) { for (T t : list) { if (t.equals(obj)) return t; } return null; } public static List castAndMap(List list, Class castClass) { List l = new ArrayList<>(); for (T t : list) { if (castClass.isAssignableFrom(t.getClass())) l.add((R) t); } return l; } public static T findFirstOrNull(List list, Predicate predicate) { for (T t : list) { if (predicate.test(t)) return t; } return null; } public static boolean anyMatch(List list, Predicate predicate) { for (T t : list) { if (predicate.test(t)) return true; } return false; } @Environment(EnvType.CLIENT) public static boolean anyMatchEqualsAll(List> list, EntryStack stack) { return firstOrNullEqualsAll(list, stack) != null; } @Environment(EnvType.CLIENT) public static boolean anyMatchEqualsEntryIgnoreAmount(List> list, EntryStack stack) { return findFirstOrNullEqualsEntryIgnoreAmount(list, stack) != null; } @Environment(EnvType.CLIENT) public static EntryStack firstOrNullEqualsAll(List> list, EntryStack stack) { for (EntryStack t : list) { if (EntryStacks.equalsExact(t, stack)) return t; } return null; } @Environment(EnvType.CLIENT) public static EntryStack findFirstOrNullEqualsEntryIgnoreAmount(Collection> list, EntryStack stack) { for (EntryStack t : list) { if (EntryStacks.equalsIgnoreCount(t, stack)) return t; } return null; } public static List filter(List list, Predicate predicate) { List l = Lists.newArrayList(); for (T t : list) { if (predicate.test(t)) { l.add(t); } } return l; } public static Set filter(Set list, Predicate predicate) { Set l = Sets.newLinkedHashSet(); for (T t : list) { if (predicate.test(t)) { l.add(t); } } return l; } public static List filterSetToList(Set list, Predicate predicate) { List l = Lists.newArrayList(); for (T t : list) { if (predicate.test(t)) { l.add(t); } } return l; } public static List map(List list, Function function) { List l = new ArrayList<>(list.size() + 1); for (T t : list) { l.add(function.apply(t)); } return l; } public static List map(Collection list, Function function) { List l = new ArrayList<>(list.size() + 1); for (T t : list) { l.add(function.apply(t)); } return l; } public static IntList mapToInt(Collection list, ToIntFunction function) { IntList l = new IntArrayList(list.size() + 1); for (T t : list) { l.add(function.applyAsInt(t)); } return l; } public static List mapParallel(Collection list, Function function) { return list.parallelStream().map(function).collect(Collectors.toList()); } public static > C mapParallel(Collection list, Function function, Supplier supplier) { return list.parallelStream().map(function).collect(Collectors.toCollection(supplier)); } public static List map(T[] list, Function function) { List l = new ArrayList<>(list.length + 1); for (T t : list) { l.add(function.apply(t)); } return l; } public static Optional mapAndMax(List list, Function function, Comparator comparator) { if (list.isEmpty()) return Optional.empty(); return list.stream().max(Comparator.comparing(function, comparator)).map(function); } public static Optional mapAndMax(T[] list, Function function, Comparator comparator) { if (list.length <= 0) return Optional.empty(); return Stream.of(list).max(Comparator.comparing(function, comparator)).map(function); } public static Optional max(List list, Comparator comparator) { if (list.isEmpty()) return Optional.empty(); return list.stream().max(comparator); } public static Optional max(T[] list, Comparator comparator) { if (list.length <= 0) return Optional.empty(); return Stream.of(list).max(comparator); } public static String joinToString(List list, String separator) { StringJoiner joiner = new StringJoiner(separator); for (String t : list) { joiner.add(t); } return joiner.toString(); } public static String joinToString(String[] list, String separator) { StringJoiner joiner = new StringJoiner(separator); for (String t : list) { joiner.add(t); } return joiner.toString(); } public static String mapAndJoinToString(List list, Function function, String separator) { StringJoiner joiner = new StringJoiner(separator); for (T t : list) { joiner.add(function.apply(t)); } return joiner.toString(); } public static String mapAndJoinToString(T[] list, Function function, String separator) { StringJoiner joiner = new StringJoiner(separator); for (T t : list) { joiner.add(function.apply(t)); } return joiner.toString(); } public static List filterAndMap(List list, Predicate predicate, Function function) { List l = null; for (T t : list) { if (predicate.test(t)) { if (l == null) l = Lists.newArrayList(); l.add(function.apply(t)); } } return l == null ? Collections.emptyList() : l; } public static int sumInt(List list, Function function) { int sum = 0; for (T t : list) { sum += function.apply(t); } return sum; } public static int sumInt(List list) { int sum = 0; for (int t : list) { sum += t; } return sum; } public static double sumDouble(List list, Function function) { double sum = 0; for (T t : list) { sum += function.apply(t); } return sum; } public static double sumDouble(List list) { double sum = 0; for (double t : list) { sum += t; } return sum; } public static Iterable> partition(List list, int size) { return () -> new UnmodifiableIterator>() { int i = 0; int partitionSize = Mth.ceil(list.size() / (float) size); @Override public boolean hasNext() { return i < partitionSize; } @Override public Iterable next() { UnmodifiableIterator iterator = new UnmodifiableIterator() { int cursor = i++ * size; int curSize = cursor + Math.min(list.size() - cursor, size); @Override public boolean hasNext() { return cursor < curSize; } @Override public T next() { return list.get(cursor++); } }; return () -> iterator; } }; } }