java-commons/src/main/java/io/gitlab/jfronny/commons/tuple/Tuple.java

94 lines
2.8 KiB
Java

package io.gitlab.jfronny.commons.tuple;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Function;
public record Tuple<T1, T2>(@Nullable T1 left, @Nullable T2 right) {
@Contract(pure = true) @NotNull
public static <T1, T2> Tuple<T1, T2> of(@Nullable T1 left, @Nullable T2 right) {
return new Tuple<>(left, right);
}
@Contract(pure = true) @NotNull
public static <T1, T2> Tuple<T1, T2> from(@NotNull Map.Entry<T1, T2> entry) {
Objects.requireNonNull(entry);
return new Tuple<>(entry.getKey(), entry.getValue());
}
@Contract(pure = true) @NotNull
public <T> Tuple<T, T2> mapLeft(@NotNull Function<T1, T> mapper) {
return new Tuple<>(Objects.requireNonNull(mapper).apply(left), right);
}
@Contract(pure = true) @NotNull
public <T> Tuple<T1, T> mapRight(@NotNull Function<T2, T> mapper) {
return new Tuple<>(left, Objects.requireNonNull(mapper).apply(right));
}
@Contract(pure = true) @NotNull
public Tuple<T2, T1> swap() {
return new Tuple<>(right, left);
}
@Contract(pure = true)
public static <T1, T2> Set<Tuple<T1, T2>> from(@NotNull Map<T1, T2> map) {
Objects.requireNonNull(map);
return new AbstractSet<>() {
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public boolean contains(Object o) {
if (o instanceof Tuple tup) {
if (map.containsKey(tup.left) && map.get(tup.left) == tup.right)
return true;
}
if (map.containsKey(o))
return true;
return false;
}
@NotNull
@Override
public Iterator<Tuple<T1, T2>> iterator() {
return map.entrySet().stream().map(Tuple::from).iterator();
}
@NotNull
@Override
public Object[] toArray() {
return map.entrySet().stream().map(Tuple::from).toArray();
}
@Override
public boolean add(Tuple<T1, T2> t1T2Tuple) {
return map.put(t1T2Tuple.left, t1T2Tuple.right) == null;
}
@Override
public boolean remove(Object o) {
if (o instanceof Tuple t) {
return map.remove(t.left, t.right);
}
return map.remove(o) != null;
}
@Override
public void clear() {
map.clear();
}
};
}
}