在Java 8中迭代数组的功能操作

时间:2017-05-06 02:57:37

标签: java functional-programming

因此,为了跟上时代的步伐,我想了解一下Java 8的新功能操作。除了看起来更好的观点,这完全是基于观点的,有人会喜欢详细描述使用Java 8的新函数编程风格来迭代数组的积极因素(也可能是负面的)吗?

这就是我的意思:

Pre-Java 8:

    for(Object item: itemList){
        item.doSomething();
    }

Java 8:

    itemList.stream().forEach((item) -> {
        item.doSomething();
    });

答案让我很开明,所以我会写一些东西来展示它的潜力。

    static int pos = 0;

    public static void main(String[] args) {
        List<Worker> workers = Arrays.asList(new Worker[1000]);
        workers.replaceAll(worker -> new Worker(pos++));
        workers.parallelStream().forEach(Worker::startJob);
    }

    public static class Worker {
        final int pos;

        public Worker(int pos) {
            this.pos = pos;
        }

        public synchronized void startJob() {
            try {
                wait(100);
            } catch (InterruptedException ex) {
                Logger.global.log(Level.SEVERE, null, ex);
            }
            System.out.println("Finished... " + pos);
        }
    }

1 个答案:

答案 0 :(得分:1)

只有部分答案,但迭代器的一般要点是从外部迭代转移到内部迭代。 foreach只是一个替代品,但考虑以下内容(来自 Java 8 Lambdas )模拟投掷两个骰子:

public Map < Integer, Double > parallelDiceRolls() { 
  double fraction = 1.0 / N; 
  return IntStream.range( 0, N) .parallel()
    .mapToObj( twoDiceThrows())
    .collect( groupingBy( side -> side, summingDouble( n -> fraction)));
}

这是针对流运行并行操作,删除所有外部迭代要求和所有手动线程要求。它取代了50-60行代码。

它也从关注如何完成某些事情(例如OP的Java之前的8例子)转变为完成的事情。

考虑具有Artist方法的.isFrom(String)类。在OP的第一个例子中,要计算有多少来自利物浦,代码将类似于:

int count = 0; 
for (Artist artist : allArtists) {
  if (artist.isFrom("Liverpool")) {
    count++;
  }
}

请注意,在循环和过滤中会丢失累积的愿望。对比:

allArtists.stream()
  .filter(artist -> artist.isFrom("Liverpool")
  .count();

现在逻辑很明确 - 过滤和计数。迭代现在是内部的而不是外部的。

还有许多其他示例,基本原理和首选项。但我认为它不仅仅是“美” - 它关注的是什么,而不是当人们考虑迭代时的方式。