Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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);
}
}
}
@thinkbigthings

This comment has been minimized.

Show comment
Hide comment
@thinkbigthings

thinkbigthings Apr 21, 2018

It's cool that you can do something like this in Java 10. But I'm trying to understand how this is actually a mixin and how it is an improvement over e.g. creating a ForwardingList class and just adding the methods you want to that? Is there a way to add behavior to a class you don't have control over (like java List classes) without writing a forwarding method to re-implement the entire interface (as with ForwardingList here)?

It's cool that you can do something like this in Java 10. But I'm trying to understand how this is actually a mixin and how it is an improvement over e.g. creating a ForwardingList class and just adding the methods you want to that? Is there a way to add behavior to a class you don't have control over (like java List classes) without writing a forwarding method to re-implement the entire interface (as with ForwardingList here)?

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