
ru.progrm_jarvis.javacommons.util.stream.EnumCollectors Maven / Gradle / Ivy
package ru.progrm_jarvis.javacommons.util.stream;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ru.progrm_jarvis.javacommons.util.TypeHints;
import ru.progrm_jarvis.javacommons.util.TypeHints.TypeHint;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
/**
* {@link Collector Collectors} for use with enums.
*
* There also are some overloads with automatic type inference.
* These methods delegate their logic to the corresponding methods with explicit type parameter
* by inferring enum types via {@link TypeHint type hints}.
* This approach leads to insignificant overhead due to empty-array allocation cost
* thus it is recommended to provide types explicitly in critical sections.
*/
@UtilityClass
public class EnumCollectors {
/**
* Returns a {@link Collector} that accumulates the input elements into a new enum-{@link Map}.
*
* @param type type object of the enum
* @param keyMapper mapping function used to convert the elements into enum-keys
* @param valueMapper mapping function used to convert the elements into values
* @param merger function used to handle duplicate values
* @param type of the input elements
* @param type of the enum
* @param type of map values
* @return a collector collecting al its elements into an enum-map
*/
public , V> @NotNull Collector> toEnumMap(
final @NonNull Class type,
final @NonNull Function keyMapper,
final @NonNull Function valueMapper,
final @NonNull BinaryOperator merger
) {
return Collectors.toMap(keyMapper, valueMapper, merger, () -> new EnumMap<>(type));
}
/**
* Returns a {@link Collector} that accumulates the input elements into a new enum-{@link Map}.
*
* @param keyMapper mapping function used to convert the elements into enum-keys
* @param valueMapper mapping function used to convert the elements into values
* @param merger function used to handle duplicate values
* @param typeHint array used for enum-type discovery
* @param type of the input elements
* @param type of the enum
* @param type of map values
* @return a collector collecting al its elements into an enum-map
*/
@SafeVarargs
public , V> @NotNull Collector> toEnumMap(
final @NonNull Function keyMapper,
final @NonNull Function valueMapper,
final @NonNull BinaryOperator merger,
@TypeHint final @Nullable E @NonNull ... typeHint
) {
return toEnumMap(TypeHints.resolve(typeHint), keyMapper, valueMapper, merger);
}
/**
* Returns a {@link Collector} that accumulates the input elements into a new enum-{@link Map}.
*
* @param type type object of the enum
* @param keyMapper mapping function used to convert the elements into enum-keys
* @param valueMapper mapping function used to convert the elements into values
* @param type of the input elements
* @param type of the enum
* @param type of map values
* @return a collector collecting al its elements into an enum-map
*/
public , V> @NotNull Collector> toEnumMap(
final @NonNull Class type,
final @NonNull Function keyMapper,
final @NonNull Function valueMapper
) {
return toEnumMap(type, keyMapper, valueMapper, throwingMerger());
}
/**
* Returns a {@link Collector} that accumulates the input elements into a new enum-{@link Map}.
*
* @param type type object of the enum
* @param valueMapper mapping function used to convert the elements into values
* @param type of the enum
* @param type of map values
* @return a collector collecting al its elements into an enum-map
*/
public , V> @NotNull Collector> toEnumMap(
final @NonNull Class type,
final @NonNull Function valueMapper
) {
return toEnumMap(type, Function.identity(), valueMapper, throwingMerger());
}
/**
* Returns a {@link Collector} that accumulates the input elements into a new enum-{@link Map}.
*
* @param type type object of the enum
* @param valueMapper mapping function used to convert the elements into values
* @param merger function used to handle duplicate values
* @param type of the enum
* @param type of map values
* @return a collector collecting al its elements into an enum-map
*/
public , V> @NotNull Collector> toEnumMap(
final @NonNull Class type,
final @NonNull Function valueMapper,
final @NonNull BinaryOperator merger
) {
return toEnumMap(type, Function.identity(), valueMapper, merger);
}
/**
* Returns a {@link Collector} that accumulates the input elements into a new enum-{@link Map}.
*
* @param valueMapper mapping function used to convert the elements into values
* @param merger function used to handle duplicate values
* @param typeHint array used for enum-type discovery
* @param type of the enum
* @param type of map values
* @return a collector collecting al its elements into an enum-map
*/
@SafeVarargs
public , V> @NotNull Collector> toEnumMap(
final @NonNull Function valueMapper,
final @NonNull BinaryOperator merger,
@TypeHint final @Nullable E @NonNull ... typeHint
) {
return toEnumMap(TypeHints.resolve(typeHint), valueMapper, merger);
}
/**
* Returns a {@link Collector} that accumulates the input elements into a new enum-{@link Set}.
*
* @param type type object of the enum
* @param type of the enum
* @return a collector collecting al its elements into an enum-set
*/
public > Collector> toEnumSet(
final @NonNull Class type
) {
return Collectors.toCollection(() -> EnumSet.noneOf(type));
}
/**
* Returns a {@link Collector} that accumulates the input elements into a new enum-{@link Set}.
*
* @param typeHint array used for enum-type discovery
* @param type of the enum
* @return a collector collecting al its elements into an enum-set
*/
@SafeVarargs
public > Collector> toEnumSet(
@TypeHint final @Nullable E @NonNull ... typeHint
) {
return toEnumSet(TypeHints.resolve(typeHint));
}
/**
* Returns a default merger for use with to-map collectors
* which throws {@link IllegalStateException} on duplicate values.
*
* @param type of the mapped value
* @return default throwing merger
*/
private static @NotNull BinaryOperator throwingMerger() {
return (left, right) -> {
throw new IllegalStateException("Duplicate elements " + left + " and " + right);
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy