Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.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
Java8GroupBy或使用通用方法_Java - Fatal编程技术网

Java8GroupBy或使用通用方法

Java8GroupBy或使用通用方法,java,Java,我得到了这个类对象的数组列表。e、 g: new Foo(1, "P1", 300, 400), new Foo(1, "P4", 300, 400), new Foo(2, "P2", 600, 400), new Foo(3, "P3", 30, 20), new Foo(3, "P3", 70, 20), new Foo(1, "P1", 360, 40), new Foo(4, "P4", 320, 200), new Foo(4, "P4", 500, 900) 我想通过创建一个新

我得到了这个类对象的数组列表。e、 g:

new Foo(1, "P1", 300, 400), 
new Foo(1, "P4", 300, 400),
new Foo(2, "P2", 600, 400),
new Foo(3, "P3", 30, 20),
new Foo(3, "P3", 70, 20),
new Foo(1, "P1", 360, 40),
new Foo(4, "P4", 320, 200),
new Foo(4, "P4", 500, 900)
我想通过创建一个新的FOO对象列表来转换这些值,该对象的总和值按id和reference分组。 它将像:

new Foo(1, "P1", 660, 440), 
new Foo(1, "P4", 300, 400),
new Foo(2, "P2", 600, 400), 
new Foo(3, "P3", 100, 40)

使用类似这样的方法,从第一个列表中获取每个项目,检查它是否存在于新列表中,如果不存在,则只将项目添加到新列表中。如果存在,则将项目的最后两个字段添加到具有相同列表中前两个字段的项目中

public ArrayList<Foo> groupList(ArrayList<Foo> list){
    ArrayList<Foo> foos = new ArrayList<Foo>();
    for(Foo foo: list){
        Foo temp = getFoo(foos, foo);
        if(temp != null){
            temp.merge(foo);
        }else{
            foos.add(foo);
        }
    }
}

public Foo getFoo(ArrayList<Foo> foos, Foo foo){
    for(Foo temp: foos){
        if(foos.equals(temp)){
            return temp;
        }
    }
    return null;
}

如果您打算进行这种“特殊”分组,则不应该(或者更确切地说:不能)使用内置的
groupBy
功能。内置函数的语义不包括要对
Foo
对象执行的“合并”操作

相反,您可以使用以下功能:

  • keyMapper
    是一个函数,用于创建一个键,即条目的某种“标识符”。在您的例子中,这是一个函数,它接受一个
    Foo
    ,并创建一个
    条目
    对象,用作映射的键。(您可以在那里使用任何
    元组
    ——即使是
    列表
    也可以)
  • valueMapper
    可以是标识功能
  • mergeFunction
    在这里很重要:它接受两个
    Foo
    对象(具有相同的数字和字符串),并返回一个新的合并
    Foo
    对象,其中添加了剩余的值
结果将是一个
映射
,但如果需要,您可以从该映射的值创建一个
列表

以下是一个例子:

import static java.util.stream.Collectors.toMap;

import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

public class GroupByTest
{
    public static void main(String[] args)
    {
        example();
        exampleUnmaintainable();
    }


    private static void example()
    {
        List<Foo> foos = Arrays.asList(
            new Foo(1, "P1", 300, 400), 
            new Foo(1, "P4", 300, 400),
            new Foo(2, "P2", 600, 400),
            new Foo(3, "P3", 30, 20),
            new Foo(3, "P3", 70, 20),
            new Foo(1, "P1", 360, 40),
            new Foo(4, "P4", 320, 200),
            new Foo(4, "P4", 500, 900)
        );

        Function<Foo, Entry<Integer, String>> keyMapper = foo -> 
            new SimpleEntry<Integer, String>(foo.getId(), foo.getS());
        Function<Foo, Foo> valueMapper = foo -> foo;
        BinaryOperator<Foo> mergeFunction = (f0, f1) ->
            new Foo(f0.getId(), f0.getS(), f0.getX()+f1.getX(), f0.getY()+f1.getY());
        Map<Entry<Integer, String>, Foo> result = 
            foos.stream().collect(toMap(keyMapper, valueMapper, mergeFunction));

        for (Entry<Entry<Integer, String>, Foo> entry : result.entrySet())
        {
            System.out.println(entry);
        }
    }


    private static void exampleUnmaintainable()
    {
        List<Foo> foos = Arrays.asList(
            new Foo(1, "P1", 300, 400), 
            new Foo(1, "P4", 300, 400),
            new Foo(2, "P2", 600, 400),
            new Foo(3, "P3", 30, 20),
            new Foo(3, "P3", 70, 20),
            new Foo(1, "P1", 360, 40),
            new Foo(4, "P4", 320, 200),
            new Foo(4, "P4", 500, 900)
        );

        List<Foo> result = foos.stream().collect(toMap(
            foo -> new SimpleEntry<Integer, String>(foo.getId(), foo.getS()), 
            foo -> foo, (f0, f1) -> new Foo(f0.getId(), f0.getS(), 
                f0.getX()+f1.getX(), f0.getY()+f1.getY())))
            .values().stream().collect(Collectors.toList());

        for (Foo foo : result)
        {
            System.out.println(foo);
        }
    }


    static class Foo
    {
        private int id;
        private String s;
        private int x;
        private int y;

        public Foo(int id, String s, int x, int y)
        {
            this.id = id;
            this.s = s;
            this.x = x;
            this.y = y;
        }

        public int getId()
        {
            return id;
        }

        public String getS()
        {
            return s;
        }

        public int getX()
        {
            return x;
        }

        public int getY()
        {
            return y;
        }

        @Override
        public String toString()
        {
            return "Foo [id=" + id + ", s=" + s + ", x=" + x + ", y=" + y + "]";
        }
    }

}
导入静态java.util.stream.Collectors.toMap;
导入java.util.AbstractMap.SimpleEntry;
导入java.util.array;
导入java.util.List;
导入java.util.Map;
导入java.util.Map.Entry;
导入java.util.function.BinaryOperator;
导入java.util.function.function;
导入java.util.stream.collector;
公共类GroupByTest
{
公共静态void main(字符串[]args)
{
示例();
例如无法维护();
}
私有静态void示例()
{
List foos=Arrays.asList(
新Foo(1,“P1”,300,400),
新富(1,P4,300400),,
新富(2,P2,600400),,
新富(3,P3,30,20),,
新富(3,P3,70,20),,
新富(1,P1,360,40),,
新富(4,P4,320200),,
新富(4,“P4”,500,900)
);
函数keyMapper=foo->
新的SimpleEntry(foo.getId(),foo.getS());
函数值映射器=foo->foo;
二进制运算符合并函数=(f0,f1)->
新的Foo(f0.getId(),f0.getS(),f0.getX()+f1.getX(),f0.getY()+f1.getY());
映射结果=
collect(toMap(keyMapper、valueMapper、mergeFunction));
for(条目:result.entrySet())
{
系统输出打印项次(输入);
}
}
私有静态void示例无法维护()
{
List foos=Arrays.asList(
新Foo(1,“P1”,300,400),
新富(1,P4,300400),,
新富(2,P2,600400),,
新富(3,P3,30,20),,
新富(3,P3,70,20),,
新富(1,P1,360,40),,
新富(4,P4,320200),,
新富(4,“P4”,500,900)
);
List result=foos.stream().collect(toMap(
foo->new SimpleEntry(foo.getId(),foo.getS()),
foo->foo,(f0,f1)->新foo(f0.getId(),f0.getS(),
f0.getX()+f1.getX(),f0.getY()+f1.getY())
.values().stream().collect(Collectors.toList());
for(Foo-Foo:result)
{
系统输出打印项次(foo);
}
}
静态类Foo
{
私有int-id;
私有字符串;
私人INTX;
私营企业;
公共Foo(int-id,字符串s,int-x,int-y)
{
this.id=id;
这个.s=s;
这个.x=x;
这个。y=y;
}
公共int getId()
{
返回id;
}
公共字符串get()
{
返回s;
}
公共int getX()
{
返回x;
}
公共int getY()
{
返回y;
}
@凌驾
公共字符串toString()
{
返回“Foo[id=“+id+”,s=“+s+”,x=“+x+”,y=“+y+””;
}
}
}

是的,一个被动的攻击性的评论:如果你不喜欢方法名等,那么你应该向我们展示你实际的
Foo
类。我们这里有一点猜测…

请阅读。它将帮助您以有助于我们帮助您的方式编写问题。@jbrown他需要一种方法,该方法将接受
Foo
s的
ArrayList
,并返回该
ArrayList
的分组版本。例如:遍历列表中的所有项目,检查将返回的列表中是否已经存在该项目,如果没有,则添加该项目,如果合并了数值。@nickzoum-只是介绍了“包含足够的代码以允许其他人重现问题”的思想,如链接文档中所述
import static java.util.stream.Collectors.toMap;

import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

public class GroupByTest
{
    public static void main(String[] args)
    {
        example();
        exampleUnmaintainable();
    }


    private static void example()
    {
        List<Foo> foos = Arrays.asList(
            new Foo(1, "P1", 300, 400), 
            new Foo(1, "P4", 300, 400),
            new Foo(2, "P2", 600, 400),
            new Foo(3, "P3", 30, 20),
            new Foo(3, "P3", 70, 20),
            new Foo(1, "P1", 360, 40),
            new Foo(4, "P4", 320, 200),
            new Foo(4, "P4", 500, 900)
        );

        Function<Foo, Entry<Integer, String>> keyMapper = foo -> 
            new SimpleEntry<Integer, String>(foo.getId(), foo.getS());
        Function<Foo, Foo> valueMapper = foo -> foo;
        BinaryOperator<Foo> mergeFunction = (f0, f1) ->
            new Foo(f0.getId(), f0.getS(), f0.getX()+f1.getX(), f0.getY()+f1.getY());
        Map<Entry<Integer, String>, Foo> result = 
            foos.stream().collect(toMap(keyMapper, valueMapper, mergeFunction));

        for (Entry<Entry<Integer, String>, Foo> entry : result.entrySet())
        {
            System.out.println(entry);
        }
    }


    private static void exampleUnmaintainable()
    {
        List<Foo> foos = Arrays.asList(
            new Foo(1, "P1", 300, 400), 
            new Foo(1, "P4", 300, 400),
            new Foo(2, "P2", 600, 400),
            new Foo(3, "P3", 30, 20),
            new Foo(3, "P3", 70, 20),
            new Foo(1, "P1", 360, 40),
            new Foo(4, "P4", 320, 200),
            new Foo(4, "P4", 500, 900)
        );

        List<Foo> result = foos.stream().collect(toMap(
            foo -> new SimpleEntry<Integer, String>(foo.getId(), foo.getS()), 
            foo -> foo, (f0, f1) -> new Foo(f0.getId(), f0.getS(), 
                f0.getX()+f1.getX(), f0.getY()+f1.getY())))
            .values().stream().collect(Collectors.toList());

        for (Foo foo : result)
        {
            System.out.println(foo);
        }
    }


    static class Foo
    {
        private int id;
        private String s;
        private int x;
        private int y;

        public Foo(int id, String s, int x, int y)
        {
            this.id = id;
            this.s = s;
            this.x = x;
            this.y = y;
        }

        public int getId()
        {
            return id;
        }

        public String getS()
        {
            return s;
        }

        public int getX()
        {
            return x;
        }

        public int getY()
        {
            return y;
        }

        @Override
        public String toString()
        {
            return "Foo [id=" + id + ", s=" + s + ", x=" + x + ", y=" + y + "]";
        }
    }

}