Skip to content

Instantly share code, notes, and snippets.

@benjiman
Created November 10, 2017 16:21
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save benjiman/a8945f378691f4c1d258a12bed825ec2 to your computer and use it in GitHub Desktop.
Anonymous Types with Java 10
package com.benjiweber.anontypes;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
public class Example {
public static void main(String... args) {
var x = (Quacks & Waddles) Mixin::create;
x.quack(); // prints Quacking
x.waddle(); // prints Waddling
var y = (IsA<List<String>> & Mappable<String> & FlatMappable<String> & Joinable<String>)
() -> List.of("Anonyous", "Types");
System.out.println(y.join(",") + " - " + y.size()); // prints Anonymous,Types - 2
System.out.println(y.map(i -> i+i)); // prints [AnonyousAnonyous, TypesTypes]
System.out.println(y.flatMap(i -> List.of(i.split("")))); // prints [A, n, o, n, y, o, u, s, T, y, p, e, s]
}
interface Mixin {
void __noop__();
static void create() {}
}
interface Quacks extends Mixin {
default void quack() {
System.out.println("Quacking");
}
}
interface Waddles extends Mixin {
default void waddle() {
System.out.println("Waddling");
}
}
interface IsA<T> {
T delegate();
}
interface Mappable<T> extends ForwardingList<T> {
default <R> List<R> map(Function<? super T, ? extends R> mapper) {
return delegate().stream().map(mapper).collect(toList());
}
}
interface FlatMappable<T> extends ForwardingList<T> {
default <R> List<R> flatMap(Function<? super T, ? extends List<? extends R>> mapper) {
return delegate().stream().flatMap(i -> mapper.apply(i).stream()).collect(toList());
}
}
interface Joinable<T extends CharSequence> extends ForwardingList<T> {
default String join(CharSequence delimiter) {
return delegate().stream().collect(Collectors.joining(delimiter));
}
}
interface ForwardingList<T> extends List<T>, IsA<List<T>> {
List<T> delegate();
default int size() {
return delegate().size();
}
default boolean isEmpty() {
return delegate().isEmpty();
}
default boolean contains(Object o) {
return delegate().contains(o);
}
default Iterator<T> iterator() {
return delegate().iterator();
}
default Object[] toArray() {
return delegate().toArray();
}
default <T1> T1[] toArray(T1[] a) {
return delegate().toArray(a);
}
default boolean add(T t) {
return delegate().add(t);
}
default boolean remove(Object o) {
return delegate().remove(o);
}
default boolean containsAll(Collection<?> c) {
return delegate().containsAll(c);
}
default boolean addAll(Collection<? extends T> c) {
return delegate().addAll(c);
}
default boolean addAll(int index, Collection<? extends T> c) {
return delegate().addAll(index, c);
}
default boolean removeAll(Collection<?> c) {
return delegate().removeAll(c);
}
default boolean retainAll(Collection<?> c) {
return delegate().retainAll(c);
}
default void replaceAll(UnaryOperator<T> operator) {
delegate().replaceAll(operator);
}
default void sort(Comparator<? super T> c) {
delegate().sort(c);
}
default void clear() {
delegate().clear();
}
default T get(int index) {
return delegate().get(index);
}
default T set(int index, T element) {
return delegate().set(index, element);
}
default void add(int index, T element) {
delegate().add(index, element);
}
default T remove(int index) {
return delegate().remove(index);
}
default int indexOf(Object o) {
return delegate().indexOf(o);
}
default int lastIndexOf(Object o) {
return delegate().lastIndexOf(o);
}
default ListIterator<T> listIterator() {
return delegate().listIterator();
}
default ListIterator<T> listIterator(int index) {
return delegate().listIterator(index);
}
default List<T> subList(int fromIndex, int toIndex) {
return delegate().subList(fromIndex, toIndex);
}
default Spliterator<T> spliterator() {
return delegate().spliterator();
}
default boolean removeIf(Predicate<? super T> filter) {
return delegate().removeIf(filter);
}
default Stream<T> stream() {
return delegate().stream();
}
default Stream<T> parallelStream() {
return delegate().parallelStream();
}
default void forEach(Consumer<? super T> action) {
delegate().forEach(action);
}
}
}
@Dicee
Copy link

Dicee commented Nov 7, 2018

You're using this feature very creatively but it feels pretty hacky. I wouldn't recommend anyone to use this in real code (but perhaps you wouldn't either!). It was interesting to see though, it wouldn't have crossed my mind to try this kind of things!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment