Last active
October 20, 2022 07:33
-
-
Save passos/01d201f9d872de2f8783fec3fd346132 to your computer and use it in GitHub Desktop.
A very simple stream class for Java 8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.android.utils; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collection; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
public class Stream<T> { | |
private Collection<T> data; | |
public static <T> Stream<T> of(Collection<T> data) { | |
return new Stream<>(data); | |
} | |
public static <T> Stream<T> of(T... data) { | |
return new Stream<>(Arrays.asList(data)); | |
} | |
public Stream(Collection<T> data) { | |
this.data = data == null ? Collections.emptyList() : data; | |
} | |
public interface Func<T, R> { | |
R apply(T element); | |
} | |
public interface VoidFunc<T> { | |
void apply(T element); | |
} | |
public interface Predicate<T> { | |
boolean test(T element); | |
} | |
public interface ReducerFunc<T, R> { | |
R apply(R value, T element); | |
} | |
public List<T> asList() { | |
return Collections.list(Collections.enumeration(data)); | |
} | |
public Collection<T> asCollection() { | |
return data; | |
} | |
public T[] asArray() { | |
return (T[]) data.toArray(); | |
} | |
public Set<T> asSet() { | |
return new HashSet<>(data); | |
} | |
public <K> Map<K, T> asMap(Func<? super T, K> key) { | |
Map<K, T> result = new HashMap<>(); | |
for (T item : data) { | |
result.put(key.apply(item), item); | |
} | |
return result; | |
} | |
public int count() { | |
return data.size(); | |
} | |
public Stream<T> apply(VoidFunc<? super T> func) { | |
for (T item : data) { | |
func.apply(item); | |
} | |
return this; | |
} | |
public <R> Stream<R> map(Func<? super T, ? extends R> mapper) { | |
Collection<R> result = new ArrayList<>(data.size()); | |
for (T item : data) { | |
result.add(mapper.apply(item)); | |
} | |
return Stream.of(result); | |
} | |
public <R> Stream<R> flatMap(Func<? super T, ? extends Stream<? extends R>> mapper) { | |
Collection<R> result = new ArrayList<>(data.size()); | |
for (T item : data) { | |
result.addAll(mapper.apply(item).asCollection()); | |
} | |
return Stream.of(result); | |
} | |
public Stream<T> filter(Predicate<? super T> predicate) { | |
Collection<T> result = new ArrayList<>(data.size()); | |
for (T item : data) { | |
if (predicate.test(item)) { | |
result.add(item); | |
} | |
} | |
return new Stream<>(result); | |
} | |
public <R> R reduce(ReducerFunc<T, R> reducer) { | |
return reduce(reducer, null); | |
} | |
public <R> R reduce(ReducerFunc<T, R> reducer, R initializer) { | |
R result = initializer; | |
for (T item : data) { | |
result = reducer.apply(result, item); | |
} | |
return result; | |
} | |
public Stream<T> sort() { | |
return sort(null); | |
} | |
public Stream<T> sort(Comparator<? super T> c) { | |
List<T> list = new ArrayList<>(data); | |
Collections.sort(list, c); | |
return Stream.of(list); | |
} | |
public Stream<T> copy() { | |
return new Stream<>(new ArrayList<>(data)); | |
} | |
public Stream<T> synchronize() { | |
return new Stream<>(Collections.synchronizedCollection(data)); | |
} | |
static class Node { | |
String value; | |
Node(String value) { | |
this.value = value; | |
} | |
} | |
public T first() { | |
return first(null); | |
} | |
public T first(T defaultValue) { | |
Iterator<T> iterator = data.iterator(); | |
return iterator.hasNext() ? iterator.next() : defaultValue; | |
} | |
public Stream<T> merge(Stream<T> another) { | |
data.addAll(another.data); | |
return this; | |
} | |
public Stream<T> intersect(Stream<T> another) { | |
Set<T> anotherSet = another.asSet(); | |
return filter(anotherSet::contains); | |
} | |
public Stream<T> except(Stream<T> another) { | |
Set<T> anotherSet = another.asSet(); | |
return filter(it -> !anotherSet.contains(it)); | |
} | |
public String join(String delimiter) { | |
StringBuilder sb = new StringBuilder(); | |
for (T item : data) { | |
sb.append(delimiter); | |
sb.append(item.toString()); | |
} | |
return sb.length() > 0 ? sb.substring(delimiter.length()) : ""; | |
} | |
public static void main(String[] args) { | |
Stream<Node> stream = Stream.of(new Node("x"), new Node("b"), new Node("c")); | |
String result = stream | |
.sort((o1, o2) -> o1.value.compareTo(o2.value)) | |
.map(element -> element.value + "!") | |
.reduce((value, element) -> value + "\n" + element, ""); | |
System.out.println(result); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment