如何在java中存储一组唯一的整数数组

我正在尝试在 java 中存储唯一整数数组的列表。我无法使用哈希集,因为 .equals 方法不会将具有相同值但不同引用的 int[] 等同。



千巷猫影
浏览 103回答 3
3回答

跃然一笑

一种选择是使用List<Integer>而不是int[]作为 的元素Set,这将允许您使用任何Set实现。如果必须使用数组,可以将它们存储在 a 中TreeSet<int[]>,并将自定义Comparator<int[]>传递给TreeSet构造函数。这应该可行,因为TreeSet不使用equals()andhashCode()来确定两个元素是否相同。

摇曳的蔷薇

我认为以下代码片段将是您的解决方案。如果我答对了List<Integer> numberList = new ArrayList<Integer>();int[] myInts = {1, 1, 2, 3, 3, 3, 3, 4};for (int i : myInts) {&nbsp; if (!numberList.contains(i)) {&nbsp; &nbsp; &nbsp;numberList.add(i);&nbsp; &nbsp;}}

一只斗牛犬

您可以将int[]数组包装在一个特殊的容器中,该容器会覆盖equals和hashCode:public class IntArrayHolder {&nbsp; &nbsp; private final int[] array;&nbsp; &nbsp; public IntArrayHolder(int[] array) {&nbsp; &nbsp; &nbsp; &nbsp; this.array = array;&nbsp; &nbsp; }&nbsp; &nbsp; public int[] getArray() {&nbsp; &nbsp; &nbsp; &nbsp; return array;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean equals(Object object) {&nbsp; &nbsp; &nbsp; &nbsp; if (this == object) return true;&nbsp; &nbsp; &nbsp; &nbsp; if (!(object instanceof IntArrayHolder)) return false;&nbsp; &nbsp; &nbsp; &nbsp; IntArrayHolder that = (IntArrayHolder) object;&nbsp; &nbsp; &nbsp; &nbsp; return Arrays.equals(array, that.array);&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public int hashCode() {&nbsp; &nbsp; &nbsp; &nbsp; return Arrays.hashCode(array);&nbsp; &nbsp; }}并使用Set<IntArrayHolder>而不是Set<int[]>:Set<IntArrayHolder> set = new HashSet<>();set.add(new IntArrayHolder(new int[]{0}));set.add(new IntArrayHolder(new int[]{0}));set.add(new IntArrayHolder(new int[]{1}));set.forEach(elm -> System.out.println(Arrays.toString(elm.getArray()))); // prints [1][0]您还可以将包装和解包装封装在特殊的泛型类中,并以这种方式使用它们:Set<int[]> set = new MappedSet<>(new HashSet<>(), Mapper.from(&nbsp; &nbsp; &nbsp; &nbsp; IntArrayHolder::getArray,&nbsp; &nbsp; &nbsp; &nbsp; IntArrayHolder::new));set.add(new int[]{0});set.add(new int[]{0});set.add(new int[]{1});set.forEach(elm -> System.out.println(Arrays.toString(elm))); // prints [1][0]这里是Mapper、MappedSet、MappedCollection、MappedIterable和MappedIterator:MappedArray/**&nbsp;* <h1>Mapper</h1>&nbsp;* Represents a two way function which can be used for adapting&nbsp;* {@code Type<A>} to {@code Type<B>} where {@code Type} is invariant&nbsp;* generic type.&nbsp;*&nbsp;* <h2>Invertibility</h2>&nbsp;* <p>&nbsp;* If this mapper isn't bounded result of performing {@code out(in(x))} should&nbsp;* be similar to {@code x}, no guarantees are made about their equality. The same goes&nbsp;* with {@code in(out(x))}.&nbsp;*&nbsp;* <h2>Nullability</h2>&nbsp;* <p>&nbsp;* A mapper always converts {@code null} to {@code null} and non-null references to non-null&nbsp;* references. {@code null} can be passed to {@link #out(A)} and {@link #in(B)} methods, but&nbsp;* should never be passed to {@link #doOut(A)} and {@link #doIn(B)}.&nbsp;*&nbsp;* <h2>Bounded wildcards</h2>&nbsp;* <p>&nbsp;* Bounded wildcards should never be used on {@link A} type parameter, because mapper with bounded&nbsp;* {@link A} can't be accepted by any adapter and is completely useless.&nbsp;*&nbsp;* <p>Using of bounded wildcard on {@link B} type parameter indicates that mapper can perform&nbsp;* operations in only one way see {@link #outMapper(Function)} and {@link #inMapper(Function)}.&nbsp;*&nbsp;* <h2>Unchecked functionality</h2>&nbsp;* A mapper provides unchecked functionality for not generified methods via {@link #uncheckedOut(Object)},&nbsp;* {@link #uncheckedIn(Object)} and {@link #unchecked()} methods.&nbsp;* <p>Restricting unchecked functionality can be done by using {@link #restrictAClass(Class)}&nbsp;* and {@link #restrictBClass(Class)} methods.&nbsp;*&nbsp;* <h2>Instantiation</h2>&nbsp;* The following factory methods can be used for mapper instantiation:&nbsp;* <ul>&nbsp;*&nbsp; &nbsp; &nbsp;<li>{@link #from(Function, Function)} - two ways mapper</li>&nbsp;*&nbsp; &nbsp; &nbsp;<li>{@link #outMapper(Function)} - only-out mapper</li>&nbsp;*&nbsp; &nbsp; &nbsp;<li>{@link #inMapper(Function)} - only-in mapper</li>&nbsp;* </ul>&nbsp;* <p>This interface can also be implemented from outside.&nbsp;*&nbsp;* @param <A> type parameter of adapted generic instance&nbsp;* @param <B> type parameter of generic adapter&nbsp;*/public interface Mapper<A, B> extends Function<A, B> {&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Adapts return value of adapted instance method to adapter type.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param a result of calling adapted instance method&nbsp; &nbsp; &nbsp;* @return result which should be return from adapter&nbsp; &nbsp; &nbsp;* @implNote this method isn't supposed to be overridden, instead {@link #doOut(A)}&nbsp; &nbsp; &nbsp;* method should be implemented for defining mapper behaviour&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract("null -> null; !null -> !null")&nbsp; &nbsp; @Final&nbsp; &nbsp; default @Nullable B out(@Nullable A a) {&nbsp; &nbsp; &nbsp; &nbsp; return a == null ? null : doOut(a);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Adapts input argument of adapter method to adapted instance type.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param b argument passed to adapter method&nbsp; &nbsp; &nbsp;* @return argument which should be passed to adapted instance&nbsp; &nbsp; &nbsp;* @implNote this method isn't supposed to be overridden, instead {@link #doIn(B)}&nbsp; &nbsp; &nbsp;* method should be implemented for defining mapper behaviour&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract("null -> null; !null -> !null")&nbsp; &nbsp; @Final&nbsp; &nbsp; default @Nullable A in(@Nullable B b) {&nbsp; &nbsp; &nbsp; &nbsp; return b == null ? null : doIn(b);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Adapts return value of not generified adapted instance method to adapter type,&nbsp; &nbsp; &nbsp;* uses unchecked cast.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param a result of calling adapted instance method, is to have {@link A} type&nbsp; &nbsp; &nbsp;* @return result which should be return from adapter&nbsp; &nbsp; &nbsp;* @see #out(A)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @SuppressWarnings("unchecked") // unchecked is indicated in the method name&nbsp; &nbsp; @Contract("null -> null; !null -> !null")&nbsp; &nbsp; @Final&nbsp; &nbsp; default @Nullable B uncheckedOut(@Nullable Object a) {&nbsp; &nbsp; &nbsp; &nbsp; return out((A) a);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Adapts input argument of not generified adapter method to adapted instance type,&nbsp; &nbsp; &nbsp;* uses unchecked cast.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param b argument passed to adapter method, is to have {@link B} type&nbsp; &nbsp; &nbsp;* @return argument which should be passed to adapted instance&nbsp; &nbsp; &nbsp;* @see #in(B)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @SuppressWarnings("unchecked") // unchecked is indicated in the method name&nbsp; &nbsp; @Contract("null -> null; !null -> !null")&nbsp; &nbsp; @Final&nbsp; &nbsp; default @Nullable A uncheckedIn(@Nullable Object b) {&nbsp; &nbsp; &nbsp; &nbsp; return in((B) b);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Performs adapting of {@link A} to {@link B}.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param a input argument, mustn't be {@code null}&nbsp; &nbsp; &nbsp;* @return adaptation result, mustn't be {@code null}. If adaptation has failed {@link IllegalArgumentException}&nbsp; &nbsp; &nbsp;* should be thrown or null-object should be returned.&nbsp; &nbsp; &nbsp;* @apiNote this method isn't supposed to be called, instead {@link #out(A)} method should be used&nbsp; &nbsp; &nbsp;* @implNote this method is supposed to be implemented for defining {@link #out(A)} method behaviour&nbsp; &nbsp; &nbsp;* @see #out(A)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @NotNull B doOut(@NotNull A a);&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Performs adapting of {@link B} to {@link A}.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param b input argument, mustn't be {@code null}&nbsp; &nbsp; &nbsp;* @return adaptation result, mustn't be {@code null}. If adaptation has failed {@link IllegalArgumentException}&nbsp; &nbsp; &nbsp;* should be thrown or null-object should be returned.&nbsp; &nbsp; &nbsp;* @apiNote this method isn't supposed to be called, instead {@link #in(B)} method should be used&nbsp; &nbsp; &nbsp;* @implNote this method is supposed to be implemented for defining {@link #in(B)} method behaviour&nbsp; &nbsp; &nbsp;* @see #in(B)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @NotNull A doIn(@NotNull B b);&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Non-null analog of {@link #out(A)}.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param a input argument&nbsp; &nbsp; &nbsp;* @return mapping result&nbsp; &nbsp; &nbsp;* @apiNote {@code mapper::apply} shouldn't be used, instead mapper instance itself&nbsp; &nbsp; &nbsp;* should be used as a {@code Function<A, B>}&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Override&nbsp; &nbsp; default @NotNull B apply(@NotNull A a) {&nbsp; &nbsp; &nbsp; &nbsp; return out(a);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Non-null analog of {@link #in(B)}.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param b input argument&nbsp; &nbsp; &nbsp;* @return mapping result&nbsp; &nbsp; &nbsp;* @apiNote {@code mapper::undo} shouldn't be used, instead {@link #reverse()}&nbsp; &nbsp; &nbsp;* should be used as a {@code Function<B, A>}&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; default @NotNull A undo(@NotNull B b) { return in(b); }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Returns reverse view of this mapper.&nbsp; &nbsp; &nbsp;* <p>Some mappers may perform reverse view caching, so it's likely that&nbsp; &nbsp; &nbsp;* {@code mapper.reverse() == mapper.reverse()} and {@code mapper.reverse().reverse() == mapper}&nbsp; &nbsp; &nbsp;* will be true.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @return reverse view of this mapper&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; default Mapper<B, A> reverse() {&nbsp; &nbsp; &nbsp; &nbsp; return new Mapper<B, A>() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public @NotNull A doOut(@NotNull B b) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Mapper.this.doIn(b);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public @NotNull B doIn(@NotNull A a) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Mapper.this.doOut(a);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public Mapper<A, B> reverse() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Mapper.this;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Returns this mapper after unchecked casting to required type.&nbsp; &nbsp; &nbsp;* <p>Should be used carefully: sometimes {@link #reverse()}{@code .unchecked()} is required instead&nbsp; &nbsp; &nbsp;* of {@code unchecked()}.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param <A2> {@link A} type parameter of returned mapper&nbsp; &nbsp; &nbsp;* @return this instance&nbsp; &nbsp; &nbsp;* @see #uncheckedIn(Object)&nbsp; &nbsp; &nbsp;* @see #uncheckedOut(Object)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @SuppressWarnings("unchecked") // unchecked is indicated in the method name&nbsp; &nbsp; @Contract(value = "-> this", pure = true)&nbsp; &nbsp; default <A2> Mapper<A2, B> unchecked() {&nbsp; &nbsp; &nbsp; &nbsp; return (Mapper<A2, B>) this;&nbsp; &nbsp; }&nbsp; &nbsp; @SuppressWarnings("unchecked") // unchecked is indicated in the method name&nbsp; &nbsp; default <A2, B2> Mapper<A2, B2> doubleUnchecked() {&nbsp; &nbsp; &nbsp; &nbsp; return (Mapper<A2, B2>) this;&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Creates a composed mapper from {@link V} to {@link B} which uses {@code before}&nbsp; &nbsp; &nbsp;* mapper and this mapper in order required by operations.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param <V>&nbsp; &nbsp; the first type parameter of {@code before} mapper, and of the&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;composed mapper&nbsp; &nbsp; &nbsp;* @param before the additional mapper&nbsp; &nbsp; &nbsp;* @return a composed mapper&nbsp; &nbsp; &nbsp;* @see #andThenMapper(Mapper)&nbsp; &nbsp; &nbsp;* @see #compose(Function)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract(value = "_ -> new", pure = true)&nbsp; &nbsp; default <V> Mapper<V, B> composeMapper(Mapper<V, A> before) {&nbsp; &nbsp; &nbsp; &nbsp; return before.andThenMapper(this);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Creates a composed mapper from {@link A} to {@link C} which uses this&nbsp; &nbsp; &nbsp;* mapper and {@code after} mapper in order required by operations.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param <C>&nbsp; &nbsp;the second type parameter of {@code after} mapper, and of the&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; composed mapper&nbsp; &nbsp; &nbsp;* @param after the additional mapper&nbsp; &nbsp; &nbsp;* @return a composed mapper&nbsp; &nbsp; &nbsp;* @see #composeMapper(Mapper)&nbsp; &nbsp; &nbsp;* @see #andThen(Function)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract(value = "_ -> new", pure = true)&nbsp; &nbsp; default <C> Mapper<A, C> andThenMapper(Mapper<B, C> after) {&nbsp; &nbsp; &nbsp; &nbsp; return from(a -> after.out(out(a)), c -> in(after.in(c)));&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Creates mapper which restricts {@link A} class, so type of {@link #out(A)} operation parameter&nbsp; &nbsp; &nbsp;* is checked before performing operation.&nbsp; &nbsp; &nbsp;* <p>If parameter isn't an {@code instanceof clazz} {@link #uncheckedMap(Object)} is used.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param clazz {@link A} class&nbsp; &nbsp; &nbsp;* @return mapper which restricts {@link A} class&nbsp; &nbsp; &nbsp;* @see #restrictBClass(Class)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract(value = "_ -> new", pure = true)&nbsp; &nbsp; default Mapper<A, B> restrictAClass(Class<A> clazz) {&nbsp; &nbsp; &nbsp; &nbsp; return from(a -> clazz.isAssignableFrom(a.getClass()) ? doOut(a) : uncheckedMap(a), this::doIn);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Creates mapper which restricts {@link B} class, so type of {@link #in(B)} operation parameter&nbsp; &nbsp; &nbsp;* is checked before performing operation.&nbsp; &nbsp; &nbsp;* <p>If parameter isn't an {@code instanceof clazz} {@link #uncheckedMap(Object)} is used.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param clazz {@link B} class&nbsp; &nbsp; &nbsp;* @return mapper which restricts {@link B} class&nbsp; &nbsp; &nbsp;* @see #restrictAClass(Class)&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract(value = "_ -> new", pure = true)&nbsp; &nbsp; default Mapper<A, B> restrictBClass(Class<B> clazz) {&nbsp; &nbsp; &nbsp; &nbsp; return from(this::doOut, b -> clazz.isAssignableFrom(b.getClass()) ? doIn(b) : uncheckedMap(b));&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Creates mapper from given functions.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param out function for performing {@link #doOut(A)} method&nbsp; &nbsp; &nbsp;* @param in&nbsp; function for performing {@link #doIn(B)} method&nbsp; &nbsp; &nbsp;* @param <A> returned mapper first type parameter&nbsp; &nbsp; &nbsp;* @param <B> returned mapper second type parameter&nbsp; &nbsp; &nbsp;* @return created mapper&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract(value = "_, _ -> new", pure = true)&nbsp; &nbsp; static <A, B> Mapper<A, B> from(Function<? super A, ? extends B> out, Function<? super B, ? extends A> in) {&nbsp; &nbsp; &nbsp; &nbsp; return new Mapper<A, B>() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; private @Nullable Mapper<B, A> reverse = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public @NotNull B doOut(@NotNull A a) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return out.apply(a);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public @NotNull A doIn(@NotNull B b) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return in.apply(b);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public Mapper<B, A> reverse() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (reverse == null) ? (reverse = Mapper.super.reverse()) : reverse;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Creates mapper that can only normally perform {@link #out(A)} operation.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* <p>The returned mapper is bounded so {@link #in(B)} operation without using <i>unchecked functionality</i>&nbsp; &nbsp; &nbsp;* can only be called with {@code null} argument, according to the contract this will lead to&nbsp; &nbsp; &nbsp;* returning of {@code null}.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param out function for performing {@link #doOut(A)} method&nbsp; &nbsp; &nbsp;* @param <A> returned mapper first type parameter&nbsp; &nbsp; &nbsp;* @param <B> returned mapper second type parameter&nbsp; &nbsp; &nbsp;* @return mapper that only provides {@link #out(A)} operation&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract(value = "_ -> new", pure = true)&nbsp; &nbsp; static <A, B> Mapper<A, ? extends B> outMapper(Function<? super A, ? extends B> out) {&nbsp; &nbsp; &nbsp; &nbsp; return from(out, Mapper::uncheckedMap);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Creates mapper that can only normally perform {@link #in(B)} operation.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* <p>The returned mapper is bounded so {@link #out(A)} result can be used only as {@link Object}.&nbsp; &nbsp; &nbsp;* <p>Returned mapper guarantees that {@code out(x) == x} will always be {@code true}.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param in&nbsp; function for performing {@link #doIn(B)} method&nbsp; &nbsp; &nbsp;* @param <A> returned mapper first type parameter&nbsp; &nbsp; &nbsp;* @param <B> returned mapper second type parameter&nbsp; &nbsp; &nbsp;* @return mapper that only provides {@link #in(B)} operation&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract(value = "_ -> new", pure = true)&nbsp; &nbsp; static <A, B> Mapper<A, ? super B> inMapper(Function<? super B, ? extends A> in) {&nbsp; &nbsp; &nbsp; &nbsp; return from(Mapper::uncheckedMap, in);&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Creates mapper that maps any object to itself.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param <T> returned mapper type parameter&nbsp; &nbsp; &nbsp;* @return created mapper&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @Contract(value = "-> new", pure = true)&nbsp; &nbsp; static <T> Mapper<T, T> identity() {&nbsp; &nbsp; &nbsp; &nbsp; return from(Function.identity(), Function.identity());&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Performs unchecked cast of input to required type,&nbsp; &nbsp; &nbsp;* this method may also do some logging.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* <p>This method is supposed to be used when impossible to call {@code Function<? extends A, B>} or&nbsp; &nbsp; &nbsp;* returning {@link Object} {@code Function<A, ? super B>} is needed.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* <p>In some cases it can also be called when {@code a} appeared to be not an {@code instanceof Class<A>}.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param a&nbsp; &nbsp;input argument&nbsp; &nbsp; &nbsp;* @param <A> input argument type&nbsp; &nbsp; &nbsp;* @param <B> required type&nbsp; &nbsp; &nbsp;* @return result of unchecked cast&nbsp; &nbsp; &nbsp;* @deprecated unchecked cast&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; @SuppressWarnings({"Contract", "unchecked"}) // unchecked is indicated in the method name&nbsp; &nbsp; @Contract("_ -> param1")&nbsp; &nbsp; @Deprecated&nbsp; &nbsp; @WarnOnUse(exceptClasses = Mapper.class)&nbsp; &nbsp; static <A, B> B uncheckedMap(A a) {&nbsp; &nbsp; &nbsp; &nbsp; return (B) a;&nbsp; &nbsp; }}public class MappedSet<E, E2> extends MappedCollection<E, E2> implements Set<E2> {&nbsp; &nbsp; public MappedSet(Set<E> set, Mapper<E, E2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; super(set, mapper);&nbsp; &nbsp; }&nbsp; &nbsp; public static <E, E2> Set<E2> map(Set<E> inst, Mapper<E, E2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return new MappedSet<>(inst, mapper);&nbsp; &nbsp; }&nbsp; &nbsp; public static <E, E2> Set<? extends E2> mapOut(Set<? extends E> inst, Function<? super E, ? extends E2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return map(inst, Mapper.outMapper(mapper));&nbsp; &nbsp; }&nbsp; &nbsp; public static <E, E2> Set<? super E2> mapIn(Set<? super E> inst, Function<? super E2, ? extends E> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return map(inst, Mapper.inMapper(mapper));&nbsp; &nbsp; }}public class MappedCollection<E, E2> extends MappedIterable<E, E2> implements Collection<E2> {&nbsp; &nbsp; private final Collection<E> collection;&nbsp; &nbsp; private final Mapper<E, E2> mapper;&nbsp; &nbsp; public MappedCollection(Collection<E> collection, Mapper<E, E2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; super(collection, mapper);&nbsp; &nbsp; &nbsp; &nbsp; this.collection = collection;&nbsp; &nbsp; &nbsp; &nbsp; this.mapper = mapper;&nbsp; &nbsp; }&nbsp; &nbsp; public static <E, E2> Collection<E2> map(Collection<E> inst, Mapper<E, E2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return new MappedCollection<>(inst, mapper);&nbsp; &nbsp; }&nbsp; &nbsp; public static <E, E2> Collection<? extends E2> mapOut(Collection<? extends E> inst, Function<? super E, ? extends E2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return map(inst, Mapper.outMapper(mapper));&nbsp; &nbsp; }&nbsp; &nbsp; public static <E, E2> Collection<? super E2> mapIn(Collection<? super E> inst, Function<? super E2, ? extends E> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return map(inst, Mapper.inMapper(mapper));&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public int size() {&nbsp; &nbsp; &nbsp; &nbsp; return collection.size();&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean isEmpty() {&nbsp; &nbsp; &nbsp; &nbsp; return collection.isEmpty();&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean contains(Object o) {&nbsp; &nbsp; &nbsp; &nbsp; return collection.contains(mapper.uncheckedIn(o));&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public @NotNull Object[] toArray() {&nbsp; &nbsp; &nbsp; &nbsp; return MappedArray.map(collection.toArray(), mapper.unchecked());&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public @NotNull <T> T[] toArray(@NotNull T[] a) {&nbsp; &nbsp; &nbsp; &nbsp; return MappedArray.map(collection.toArray(), ContainersUtils.getComponentType(a), mapper.doubleUnchecked());&nbsp; &nbsp; }&nbsp; &nbsp; @Contract(mutates = "this")&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean add(@NotNull E2 e2) {&nbsp; &nbsp; &nbsp; &nbsp; return collection.add(mapper.in(e2));&nbsp; &nbsp; }&nbsp; &nbsp; @Contract(mutates = "this")&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean remove(Object o) {&nbsp; &nbsp; &nbsp; &nbsp; return collection.remove(mapper.uncheckedIn(o));&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean containsAll(@NotNull Collection<?> c) {&nbsp; &nbsp; &nbsp; &nbsp; return collection.containsAll(map(c, mapper.reverse().unchecked()));&nbsp; &nbsp; }&nbsp; &nbsp; @Contract(mutates = "this")&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean addAll(@NotNull Collection<? extends E2> c) {&nbsp; &nbsp; &nbsp; &nbsp; return collection.addAll(mapOut(c, mapper.reverse()));&nbsp; &nbsp; }&nbsp; &nbsp; @Contract(mutates = "this")&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean removeAll(@NotNull Collection<?> c) {&nbsp; &nbsp; &nbsp; &nbsp; return collection.removeAll(map(c, mapper.reverse().unchecked()));&nbsp; &nbsp; }&nbsp; &nbsp; @Contract(mutates = "this")&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean retainAll(@NotNull Collection<?> c) {&nbsp; &nbsp; &nbsp; &nbsp; return collection.retainAll(map(c, mapper.reverse().unchecked()));&nbsp; &nbsp; }&nbsp; &nbsp; @Contract(mutates = "this")&nbsp; &nbsp; @Override&nbsp; &nbsp; public void clear() {&nbsp; &nbsp; &nbsp; &nbsp; collection.clear();&nbsp; &nbsp; }}@RequiredArgsConstructorpublic class MappedIterable<E, E2> implements Iterable<E2> {&nbsp; &nbsp; private final @NotNull Iterable<E> iterable;&nbsp; &nbsp; private final @NotNull Function<? super E, ? extends E2> mapper;&nbsp; &nbsp; public static <E, E2> Iterator<E2> map(Iterator<E> inst, Function<? super E, ? extends E2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return new MappedIterator<>(inst, mapper);&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public @NotNull Iterator<E2> iterator() {&nbsp; &nbsp; &nbsp; &nbsp; return MappedIterator.map(iterable.iterator(), mapper);&nbsp; &nbsp; }}@RequiredArgsConstructorpublic class MappedIterator<E, E2> implements Iterator<E2> {&nbsp; &nbsp; private final @NotNull Iterator<E> iterator;&nbsp; &nbsp; private final @NotNull Function<? super E, ? extends E2> mapper;&nbsp; &nbsp; public static <E, E2> Iterator<E2> map(Iterator<E> inst, Function<? super E, ? extends E2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return new MappedIterator<>(inst, mapper);&nbsp; &nbsp; }&nbsp; &nbsp; @Contract(pure = true)&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean hasNext() {&nbsp; &nbsp; &nbsp; &nbsp; return iterator.hasNext();&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public E2 next() {&nbsp; &nbsp; &nbsp; &nbsp; return mapper.apply(iterator.next());&nbsp; &nbsp; }}@UtilityClasspublic class MappedArray {&nbsp; &nbsp; public static <T> Object[] map(T[] inst, Function<? super T, ?> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return Stream.of(inst).map(mapper).toArray();&nbsp; &nbsp; }&nbsp; &nbsp; public static <T, T2> T2[] map(T[] inst, Class<T2> clazz, Function<? super T, ? extends T2> mapper) {&nbsp; &nbsp; &nbsp; &nbsp; return Stream.of(inst).map(mapper).toArray(i -> ContainersUtils.createArray(clazz, i));&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java