Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类中数组上的java reduce_Java_Arrays_Java 8_Java Stream_Final - Fatal编程技术网

类中数组上的java reduce

类中数组上的java reduce,java,arrays,java-8,java-stream,final,Java,Arrays,Java 8,Java Stream,Final,我尝试使用reduce对HashMap值求和 public class Link { private double[] flows; public Link(double[] f) { setFlows(f); } public double[] getFlows() { return flows; } public void setFlows(double[] flows) { this.flow

我尝试使用reduce对HashMap值求和

public class Link 
{
    private double[] flows;
    public Link(double[] f) {
        setFlows(f);
    }
    public double[] getFlows() {
        return flows;
    }
    public void setFlows(double[] flows) {
        this.flows = flows;
    }

    public static void main(String argv[])
    {
         // TEST for reduce on HashMap
         HashMap<Integer, Link> id1 = new HashMap<Integer, Link>();
         id1.put(1, new Link(new double[]{10,1,30}));
         id1.put(2, new Link(new double[]{20,2,3}));
         id1.put(3, new Link(new double[]{30,2,3}));
         id1.put(4, new Link(new double[]{40,2,30}));

         double[] my_sum = new double[3];
         for (int i=0; i < 3; ++i)
         {
              my_sum[i] = id1.entrySet().stream().mapToDouble(e->e.getValue().getFlows()[i]).sum();
         }
         assert(my_sum[0] == 100);
         assert(my_sum[1] == 7);
         assert(my_sum[2] == 66);
    }
}
公共类链接
{
私人资金流动;
公共链接(双[]f){
设定流量(f);
}
公共双[]getFlows(){
回流;
}
公共void集合流(双[]流){
this.flows=flows;
}
公共静态void main(字符串argv[])
{
//在HashMap上测试reduce
HashMap id1=新建HashMap();
id1.put(1,新链接(新的双[]{10,1,30}));
id1.put(2,新链接(新的双[]{20,2,3}));
id1.put(3,新链接(新双[]{30,2,3}));
id1.put(4,新链接(新双[]{40,2,30}));
double[]我的总和=新的double[3];
对于(int i=0;i<3;++i)
{
my_sum[i]=id1.entrySet().stream().mapToDouble(e->e.getValue().getFlows()[i]).sum();
}
断言(my_sum[0]==100);
断言(my_sum[1]==7);
断言(my_sum[2]==66);
}
}
在for循环中,我想对Link类中每个数组项的值求和。但是,我有以下问题:

封闭范围中定义的局部变量必须是final或有效final

基本上,我不想将最终变量定义为类成员,如何解决它


还是有更好的方法来求和?(没有for循环?

你走错了路:你不应该有一个外部的
for
循环,而应该在流管道中处理所有事情

你可以让它工作

在下面的代码中,只保留映射的值(因为我们对键不感兴趣)。然后将每个值映射到它们的流。最后,首先创建一个由3个元素组成的数组(初始化为0),然后将两个双数组合并成一个结果数组,将相同索引处的值相加,从而减少生成的

我们必须依赖于在索引上使用流,因为没有内置的工具将两个流压缩在一起

double[] my_sum = 
    id1.values().stream()
                .map(Link::getFlows)
                .reduce(
                    new double[3],
                    (v1, v2) -> IntStream.range(0, v2.length).mapToDouble(i -> v1[i] + v2[i]).toArray()
                );

System.out.println(Arrays.toString(my_sum)); // prints [100.0, 7.0, 66.0]

你走错了路:你不应该有一个外部的
for
循环,而应该处理流管道中的所有事情

你可以让它工作

在下面的代码中,只保留映射的值(因为我们对键不感兴趣)。然后将每个值映射到它们的流。最后,首先创建一个由3个元素组成的数组(初始化为0),然后将两个双数组合并成一个结果数组,将相同索引处的值相加,从而减少生成的

我们必须依赖于在索引上使用流,因为没有内置的工具将两个流压缩在一起

double[] my_sum = 
    id1.values().stream()
                .map(Link::getFlows)
                .reduce(
                    new double[3],
                    (v1, v2) -> IntStream.range(0, v2.length).mapToDouble(i -> v1[i] + v2[i]).toArray()
                );

System.out.println(Arrays.toString(my_sum)); // prints [100.0, 7.0, 66.0]

如果您添加了一个
add
方法(不幸的是,使
链接变为可变的),那么您也可以使用
链接
进行求和

    // Makes it mutable - will try immutable later
    public void add(Link other) {
        for (int i = 0; i < flows.length; i++) {
            flows[i] += other.flows[i];
        }
    }

    public static void main(String argv[]) {
        // TEST for reduce on HashMap
        HashMap<Integer, Link> id1 = new HashMap<>();
        id1.put(1, new Link(new double[]{10, 1, 30}));
        id1.put(2, new Link(new double[]{20, 2, 3}));
        id1.put(3, new Link(new double[]{30, 2, 3}));
        id1.put(4, new Link(new double[]{40, 2, 30}));

        Link sum = new Link(new double[3]);
        id1.entrySet().stream().forEach(l -> sum.add(l.getValue()));
    }
//使其可变-稍后将尝试不可变
公共无效添加(链接其他){
for(int i=0;isum.add(l.getValue());
}

如果您添加了一个
add
方法(不幸的是,使
链接变为可变链接),那么您也可以使用
链接
作为总和

    // Makes it mutable - will try immutable later
    public void add(Link other) {
        for (int i = 0; i < flows.length; i++) {
            flows[i] += other.flows[i];
        }
    }

    public static void main(String argv[]) {
        // TEST for reduce on HashMap
        HashMap<Integer, Link> id1 = new HashMap<>();
        id1.put(1, new Link(new double[]{10, 1, 30}));
        id1.put(2, new Link(new double[]{20, 2, 3}));
        id1.put(3, new Link(new double[]{30, 2, 3}));
        id1.put(4, new Link(new double[]{40, 2, 30}));

        Link sum = new Link(new double[3]);
        id1.entrySet().stream().forEach(l -> sum.add(l.getValue()));
    }
//使其可变-稍后将尝试不可变
公共无效添加(链接其他){
for(int i=0;isum.add(l.getValue());
}

另一种对我来说更好的选择是使用
数组。setAll

double[] my_sum = new double[3];
Arrays.setAll(my_sum, 
  i -> id1.entrySet().stream().mapToDouble(e->e.getValue().getFlows()[i]).sum());

这里的
i
实际上是最终的。

我觉得更好的替代方法是使用
数组。setAll

double[] my_sum = new double[3];
Arrays.setAll(my_sum, 
  i -> id1.entrySet().stream().mapToDouble(e->e.getValue().getFlows()[i]).sum());

这里的
i
实际上是最终的。

可能是这里的变量
i
。尝试在循环内定义最终副本,例如
final int k=i
,然后在lambda中使用
getFlows()[k]
。还可以使用后缀增量运算符:对于
循环,i++前缀与
中的后缀一样有效。这里可能是变量
i
。尝试在循环内定义最终副本,例如
final int k=i
,然后在lambda中使用
getFlows()[k]
。还可以使用后缀增量运算符:对于
循环,i++前缀的效果与
中的后缀一样好。作为旁注,您需要以某种方式确保所有数组的长度相同。您可以在Link的构造函数中检查长度。作为旁注,您需要以某种方式确保所有数组的长度相同。你可以在Link的构造器中检查一下长度。谢谢。这里的语法更简单。谢谢。这里的语法更简单。