Laden...
My email system got horribly confused with the generics. So if you tried to copy & paste the code samples, it would not have worked.
Here they are again in plain text format.
(A small improvement is that instead of a HashMap we use a LinkedHashMap, thereby preserving the order of the initial stream. Thanks Federico for the suggestion.)
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class EnhancedStream implements Stream {
private static final class Key {
private final T t;
private final ToIntFunction hashCode;
private final BiPredicate equals;
public Key(T t, ToIntFunction hashCode,
BiPredicate equals) {
this.t = t;
this.hashCode = hashCode;
this.equals = equals;
}
public int hashCode() {
return hashCode.applyAsInt(t);
}
public boolean equals(Object obj) {
if (!(obj instanceof Key)) return false;
@SuppressWarnings("unchecked")
Key that = (Key) obj;
return equals.test(this.t, that.t);
}
}
private Stream delegate;
public EnhancedStream(Stream delegate) {
this.delegate = delegate;
}
public EnhancedStream distinct(ToIntFunction hashCode,
BiPredicate equals,
BinaryOperator merger) {
delegate = collect(Collectors.toMap(
t -> new Key(t, hashCode, equals),
t -> t,
merger,
LinkedHashMap::new))
// thanks Federico Peralta Schaffner for suggesting that
// we use a LinkedHashMap. That way we can preserve the
// original order
.values()
.stream();
return this;
}
public EnhancedStream filter(
Predicate super T> predicate) {
this.delegate = delegate.filter(predicate);
return this;
}
public EnhancedStream map(
Function super T, ? extends R> mapper) {
return new EnhancedStream(delegate.map(mapper));
}
public IntStream mapToInt(ToIntFunction super T> mapper) {
return delegate.mapToInt(mapper);
}
public LongStream mapToLong(
ToLongFunction super T> mapper) {
return delegate.mapToLong(mapper);
}
public DoubleStream mapToDouble(
ToDoubleFunction super T> mapper) {
return delegate.mapToDouble(mapper);
}
public EnhancedStream flatMap(
Function super T,
? extends Stream extends R>> mapper) {
return new EnhancedStream(delegate.flatMap(mapper));
}
public IntStream flatMapToInt(
Function super T, ? extends IntStream> mapper) {
return delegate.flatMapToInt(mapper);
}
public LongStream flatMapToLong(
Function super T, ? extends LongStream> mapper) {
return delegate.flatMapToLong(mapper);
}
public DoubleStream flatMapToDouble(
Function super T, ? extends DoubleStream> mapper) {
return delegate.flatMapToDouble(mapper);
}
public EnhancedStream distinct() {
delegate = delegate.distinct();
return this;
}
public EnhancedStream sorted() {
delegate = delegate.sorted();
return this;
}
public EnhancedStream sorted(
Comparator super T> comparator) {
delegate = delegate.sorted(comparator);
return this;
}
public EnhancedStream peek(Consumer super T> action) {
delegate = delegate.peek(action);
return this;
}
public EnhancedStream limit(long maxSize) {
delegate = delegate.limit(maxSize);
return this;
}
public EnhancedStream skip(long n) {
delegate = delegate.skip(n);
return this;
}
public EnhancedStream takeWhile(
Predicate super T> predicate) {
delegate = delegate.takeWhile(predicate);
return this;
}
public EnhancedStream dropWhile(
Predicate super T> predicate) {
delegate = delegate.dropWhile(predicate);
return this;
}
public void forEach(Consumer super T> action) {
delegate.forEach(action);
}
public void forEachOrdered(Consumer super T> action) {
delegate.forEachOrdered(action);
}
public Object[] toArray() {
return delegate.toArray();
}
public A[] toArray(IntFunction generator) {
return delegate.toArray(generator);
}
public T reduce(T identity, BinaryOperator accumulator) {
return delegate.reduce(identity, accumulator);
}
public Optional reduce(BinaryOperator accumulator) {
return delegate.reduce(accumulator);
}
public U reduce(U identity,
BiFunction accumulator,
BinaryOperator combiner) {
return delegate.reduce(identity, accumulator, combiner);
}
public R collect(Supplier supplier,
BiConsumer accumulator,
BiConsumer combiner) {
return delegate.collect(supplier, accumulator, combiner);
}
public R collect(
Collector super T, A, R> collector) {
return delegate.collect(collector);
}
public Optional min(Comparator super T> comparator) {
return delegate.min(comparator);
}
public Optional max(Comparator super T> comparator) {
return delegate.max(comparator);
}
public long count() {
return delegate.count();
}
public boolean anyMatch(Predicate super T> predicate) {
return delegate.anyMatch(predicate);
}
public boolean allMatch(Predicate super T> predicate) {
return delegate.allMatch(predicate);
}
public boolean noneMatch(Predicate super T> predicate) {
return delegate.noneMatch(predicate);
}
public Optional findFirst() {
return delegate.findFirst();
}
public Optional findAny() {
return delegate.findAny();
}
public Iterator iterator() {
return delegate.iterator();
}
public Spliterator spliterator() {
return delegate.spliterator();
}
public boolean isParallel() {
return delegate.isParallel();
}
public Stream sequential() {
return delegate.sequential();
}
public Stream parallel() {
return delegate.parallel();
}
public Stream unordered() {
return delegate.unordered();
}
public Stream onClose(Runnable closeHandler) {
return delegate.onClose(closeHandler);
}
public void close() {
delegate.close();
}
public static EnhancedStream of(T t) {
return new EnhancedStream(Stream.of(t));
}
@SafeVarargs
@SuppressWarnings("varargs")
// Creating a stream from an array is safe
public static EnhancedStream of(T... values) {
return new EnhancedStream(Arrays.stream(values));
}
}
import java.util.function.*;
public class BeachDistinctify {
public static void main(String... args) {
EnhancedStream.of("Kalathas", "Stavros", "STAVROS",
"marathi", "kalathas", "baLos", "Balos")
.distinct(HASH_CODE, EQUALS, MERGE)
.forEach(System.out::println);
}
// case insensitive hashCode() and equals()
public static final
ToIntFunction HASH_CODE =
s -> s.toUpperCase().hashCode();
public static final
BiPredicate EQUALS =
(s1, s2) ->
s1.toUpperCase().equals(s2.toUpperCase());
// keep the string with the highest total ascii value
public static final
BinaryOperator MERGE =
(s1, s2) ->
s1.chars().sum() }
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.stream.*;
public class MethodDistinctify {
public static void main(String... args) {
System.out.println("Normal ArrayDeque clone() Methods:");
EnhancedStream.of(ArrayDeque.class.getMethods())
.filter(method -> method.getName().equals("clone"))
.forEach(MethodDistinctify::print);
System.out.println();
System.out.println("Distinct ArrayDeque:");
EnhancedStream.of(ArrayDeque.class.getMethods())
.filter(method -> method.getName().equals("clone"))
.distinct(HASH_CODE, EQUALS, MERGE)
.forEach(MethodDistinctify::print);
System.out.println();
System.out.println("Normal ConcurrentSkipListSet:");
EnhancedStream.of(ConcurrentSkipListSet.class.getMethods())
.filter(method -> method.getName().contains("Set"))
.sorted(METHOD_COMPARATOR)
.forEach(MethodDistinctify::print);
System.out.println();
System.out.println("Distinct ConcurrentSkipListSet:");
EnhancedStream.of(ConcurrentSkipListSet.class.getMethods())
.filter(method -> method.getName().contains("Set"))
.distinct(HASH_CODE, EQUALS, MERGE)
.sorted(METHOD_COMPARATOR)
.forEach(MethodDistinctify::print);
}
private static void print(Method m) {
System.out.println(
Stream.of(m.getParameterTypes())
.map(Class::getSimpleName)
.collect(Collectors.joining(
", ",
" " + m.getReturnType().getSimpleName()
+ " " + m.getName() + "(",
")"))
);
}
public static final ToIntFunction HASH_CODE =
method -> method.getName().hashCode() +
method.getParameterCount();
public static final BiPredicate EQUALS =
(method1, method2) ->
method1.getName().equals(method2.getName()) &&
method1.getParameterCount() ==
method2.getParameterCount() &&
Arrays.equals(method1.getParameterTypes(),
method2.getParameterTypes());
public static final BinaryOperator MERGE =
(method1, method2) -> {
if (method1.getReturnType()
.isAssignableFrom(method2.getReturnType()))
return method2;
if (method2.getReturnType()
.isAssignableFrom(method1.getReturnType()))
return method1;
throw new IllegalArgumentException(
"Conflicting return types " +
method1.getReturnType().getCanonicalName() +
" and " +
method2.getReturnType().getCanonicalName());
};
public static final Comparator METHOD_COMPARATOR =
Comparator.comparing(Method::getName)
.thenComparing(method ->
Arrays.toString(method.getParameterTypes()));
}
Thanks for the comments so far :-)
Kind regards
Heinz
If you no longer wish to receive our emails, click the link below:
Cretesoft Limited 77 Strovolos Ave Strovolos, Lefkosia 2018 Cyprus
Laden...
Laden...