如何用lambda表达代码?

时间:2017-04-07 06:42:43

标签: lambda java-8 java-stream

我想将List转换为Map

public Map<Integer, A> toMap(List<A> list) {
    Map<Integer, A> map = new HashMap<>();
    int sum = 0;
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i).getKey() != 0) {
            sum += Math.abs(list.get(i).getKey());
            map.put(sum, list.get(i));
        }
    }
    return map;
}

如何用lambda表达呢?

2 个答案:

答案 0 :(得分:2)

使用foreach可能会更有效。当违反KISSforforeachwhile循环未死时,无需将所有内容转换为流。我稍后会给出流代码,这有点大。

的foreach

public Map<Integer, A> toMap(List<A> list) {
    Map<Integer, A> map = new HashMap<>();
    int prevKey = 0;
    for (A item : list) {
        int key = item.getKey();

        if (key != 0) {
            map.put(prevKey += Math.abs(key), item);
        }
    }
    return map;
}

结合foreach&amp;流

或者您可能需要合并foreach&amp; Stream描述做两件事filtering&amp; mapping

public Map<Integer, A> toMap(List<A> list) {
    Map<Integer, A> map = new HashMap<>();
    int prevKey = 0;
    for (A item : each(list.stream().filter(it -> it.getKey() != 0))) {
        map.put(prevKey += Math.abs(item.getKey()), item);
    }
    return map;
}

private static <T> Iterable<? extends T> each(Stream<T> stream) {
    return stream::iterator;
}

使用Stream.collect(收集器)

的流
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import static java.util.function.Function.identity;

public Map<Integer, A> toMap(List<A> list) {
    AtomicInteger prevKey = new AtomicInteger(0);
    return list.stream().filter(it -> it.getKey() != 0)
               .collect(Collectors.toMap(curry(prevKey::addAndGet, A::getKey)
                                              ,identity()));
}

// e.g: AtomicInteger.addAndGet(A.getKey())
<T, U, R> Function<T, R> curry(Function<U, R> target, Function<T, U> mapper) {
    return (it) -> target.apply(mapper.apply(it));
}
使用Stream.collect(供应商,BiConsumer,BiConsumer)

import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.stream.Collectors;
import java.util.Map;

public Map<Integer, A> toMap(List<A> list) {
    return list.stream().filter(it -> it.getKey() != 0).
            collect(Stack::new, this::calculateKey, Stack::addAll).stream().
            collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}

private void calculateKey(Stack<Entry<Integer, A>> stack, A a) {
    Integer prevKey = stack.isEmpty() ? 0 : stack.peek().getKey();

    Integer key = prevKey + a.getKey();

    stack.push(new SimpleEntry<>(key, a));
}

答案 1 :(得分:0)

这样的事情:

List<Integer> mList = Arrays.asList(1,2,3,4,5,2,-1,3,0,1);

Map<Integer, Integer> map = mList.stream()
        .filter(i -> i != 0)
        .collect(Collectors.toMap(new Function<Integer, Integer>() {
            int sum = 0;
            @Override
            public Integer apply(Integer integer) {
                sum += integer;
                return sum;
            }
        }, Function.identity()));

我已为List<Integer>完成了此操作,现在您应对List<A>执行此操作。

提示:将Integer替换为A