首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构为java 8 lambda/stream

重构为java 8 lambda/stream
EN

Stack Overflow用户
提问于 2014-08-18 16:25:37
回答 1查看 686关注 0票数 0

当我解决子集和问题或"P = NP“时,使用下面的代码需要5分钟。我真的很想知道,如果我使用.parallelStream,它会快得多。但是,我不知道如何转换代码。

代码语言:javascript
复制
public class MainActivity {
final static Integer[] POPS = {8897109, 12828837, 9461105, 6371773, 5965343, 5946800, 5582170, 5564635, 5268860, 4552402, 4335391, 4296250, 4224851, 4192887, 3439809, 3279833, 3095313, 2812896, 2783243, 2710489, 2543482, 2356285, 2226009, 2149127, 2142508, 2134411};
final static int TOTAL = 100000000;
/**
 * @param args
 */
public static void main(String[] args) {
    Combinations c = new Combinations(POPS, TOTAL);
    c.chooser();
}

}

代码语言:javascript
复制
import java.util.ArrayList;
import org.paukov.combinatorics.Factory;
import org.paukov.combinatorics.Generator;
import org.paukov.combinatorics.ICombinatoricsVector;


public class Combinations {
private Integer[] POPS;
private int TOTAL;

public combinations(Integer[] pops, int total){
    this.POPS = pops;
    this.TOTAL = total;
}

public void chooser(){
    for(int i = 1; i<=POPS.length; i++){
        System.out.println(i);
        ICombinatoricsVector<Integer> initialVector = Factory.createVector(POPS);
        Generator<Integer> gen = Factory.createSimpleCombinationGenerator(initialVector, i);
        for (ICombinatoricsVector<Integer> combination : gen) {
            String temp = combination.toString();
            int size = temp.indexOf("size");
            temp = temp.substring(22, size-3);
            int sum = Adder(temp);
            if (sum == TOTAL){
                System.out.println(temp);
            }
        }
    }
}

public int adder(String combos){
    int total = 0;
    String[] parts = combos.split(", ");
    ArrayList<Integer> nums = new ArrayList<>();
    for(int i = 0; i<parts.length; i++){
        nums.add(Integer.parseInt(parts[i]));
    }
    for(int temp : nums){
        total += temp;
    }

    return total;
}
}

这是去掉字符串内容的代码。现在只需要15秒。我意识到.parallelStream()不会大大减少它的时间,但是有人至少还能给我一些关于如何做的提示吗?

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;

import org.paukov.combinatorics.Factory;
import org.paukov.combinatorics.Generator;
import org.paukov.combinatorics.ICombinatoricsVector;


public class Combinations {
private Integer[] POPS;
private int TOTAL;

public Combinations(Integer[] pops, int total){
    this.POPS = pops;
    this.TOTAL = total;
}

public void chooser(){
    for(int i = 1; i<=POPS.length; i++){
        System.out.println(i);
        ICombinatoricsVector<Integer> initialVector = Factory.createVector(POPS);
        Generator<Integer> gen = Factory.createSimpleCombinationGenerator(initialVector, i);
        for (ICombinatoricsVector<Integer> combination : gen) {
            List<Integer> temp = combination.getVector();
            int sum = adder(temp);
            if (sum == TOTAL){
                System.out.println(temp);
            }
        }
    }
}

public int adder(List<Integer> combos){
    int total = 0;
    for(Integer temp : combos){
        total+=temp;
    }
    return total;
}
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-20 21:26:13

它在我的机箱上运行速度是我的三倍(i7-2600带有超线程,8个虚拟内核):

代码语言:javascript
复制
public class Combinations {
    private Integer[] POPS;
    private int TOTAL;

    public Combinations(Integer[] pops, int total) {
        this.POPS = pops;
        this.TOTAL = total;
    }

    public void chooser() {
        ICombinatoricsVector<Integer> initialVector = Factory.createVector(POPS);

        IntStream.range(1, POPS.length + 1).parallel()
                .peek(System.out::println)
                .mapToObj(i -> Factory.createSimpleCombinationGenerator(initialVector, i))
                .flatMap(gen -> genToStream(gen, false)
                        .map(ICombinatoricsVector::getVector)
                        .filter(v -> adder(v) == TOTAL))
                .forEach(System.out::println);
    }

    public static int adder(Iterable<Integer> combos) {
        int total = 0;
        for (Integer temp : combos) {
            total += temp;
        }
        return total;
    }

    public static <E> Stream<ICombinatoricsVector<E>> genToStream(Generator<E> gen, boolean parallel) {
        return StreamSupport.stream(Spliterators.spliterator(gen.iterator(),
                gen.getNumberOfGeneratedObjects(), Spliterator.ORDERED), parallel);
    }
}

这将使用并行流作为外部循环,规则流用于内环,并且避免使用流来对列表进行求和(为了速度)。您可以使用genToStream(gen, true)来尝试并行的内部流,但是我没有看到任何速度上的差异。

另外,如果您想要匹配的List<List<Integer>>,只需将forEach行更改为.collect(Collectors.toList());即可。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25367847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档