如果你想有一个轻量级的视图来应用和支持链接,你可以这样做:List
Function
import java.util.*;
import java.util.function.Function;
import java.util.stream.Stream;
public class MappingList<E> extends AbstractList<E> {
// using this helper class we avoid carrying <S> with the public API
static final class Source<E,S> {
final List<S> list;
final Function<? super S, ? extends E> mapper;
Source(List<S> l, Function<? super S, ? extends E> m) {
list=l;
mapper=m;
}
E get(int index) { return mapper.apply(list.get(index)); }
<T> Source map(Function<? super E, ? extends T> f) {
Objects.requireNonNull(f);
return new Source<>(list, mapper.andThen(f));
}
Stream<E> stream() { return list.stream().map(mapper); }
Stream<E> parallelStream() { return list.parallelStream().map(mapper); }
}
final Source<E,?> source;
private MappingList(Source<E,?> s) {
Objects.requireNonNull(s);
source=s;
}
@Override
public E get(int index) {
return source.get(index);
}
@Override
public int size() {
return source.list.size();
}
@Override
public Stream<E> stream() {
return source.stream();
}
@Override
public Stream<E> parallelStream() {
return source.parallelStream();
}
public <T> MappingList<T> map(Function<? super E, ? extends T> f) {
return new MappingList<>(source.map(f));
}
public static <S,T> MappingList<T> map(
List<S> l, Function<? super S, ? extends T> f) {
Objects.requireNonNull(l);
if(l instanceof MappingList)
return ((MappingList<S>)l).map(f);
return new MappingList<>(new Source<>(l, f));
}
}
它支持GUAVA风格创建映射列表,同时仍然允许将API与映射列表一起使用,懒惰地评估所有值:Stream
public static void main(String[] arg) {
List<String> strings=Arrays.asList("a", "simple", "list");
List<Integer> ints=MappingList.map(strings, s->compute(s));
List<Integer> results=MappingList.map(ints, i->compute(i));
for(int result:results) {
System.out.println("first result: "+result);
System.out.println("Not computing any more values");
break;
}
System.out.println();
System.out.println(" interacting with stream API:");
System.out.println(results.stream().filter(i-> i>500).findFirst());
}
public static int compute(String s) {
System.out.println("doing computation for "+s);
return Integer.parseInt(s, 36);
}
public static int compute(int i) {
System.out.println("doing computation for "+i);
return i*i;
}
doing computation for a
doing computation for 10
first result: 100
Not computing any more values
interacting with stream API:
doing computation for a
doing computation for 10
doing computation for simple
doing computation for 1724345618
Optional[410277188]
如果要创建具有预先计算值的 a,则只需使用 。List
new ArrayList<>(mappedList)