按属性对对象列表进行分组:Java

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21678430/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:02:27  来源:igfitidea点击:

Group a list of objects by an attribute : Java

javalistgrouping

提问by Dilukshan Mahendra

I need to group a list of objects(Student) using an attribute(Location) of the particular object, the code is like below,

我需要使用特定对象的属性(位置)对对象列表(学生)进行分组,代码如下所示,

public class Grouping {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        List<Student> studlist = new ArrayList<Student>();
        studlist.add(new Student("1726", "John", "New York"));
        studlist.add(new Student("4321", "Max", "California"));
        studlist.add(new Student("2234", "Andrew", "Los Angeles"));
        studlist.add(new Student("5223", "Michael", "New York"));
        studlist.add(new Student("7765", "Sam", "California"));
        studlist.add(new Student("3442", "Mark", "New York"));

        //Code to group students by location
        /*  Output should be Like below
            ID : 1726   Name : John Location : New York
            ID : 5223   Name : Michael  Location : New York
            ID : 4321   Name : Max  Location : California
            ID : 7765   Name : Sam  Location : California    

         */

        for (Student student : studlist) {
            System.out.println("ID : "+student.stud_id+"\t"+"Name : "+student.stud_name+"\t"+"Location : "+student.stud_location);
        }


    }
}

class Student {

    String stud_id;
    String stud_name;
    String stud_location;

    Student(String sid, String sname, String slocation) {

        this.stud_id = sid;
        this.stud_name = sname;
        this.stud_location = slocation;

    }
}

Please suggest me a clean way to do it.

请建议我一个干净的方法来做到这一点。

采纳答案by Dileep

This will add the students object to the HashMapwith locationIDas key.

这会将学生对象添加到HashMapwith locationIDas 键。

HashMap<Integer, List<Student>> hashMap = new HashMap<Integer, List<Student>>();

Iterateover this code and add students to the HashMap:

迭代此代码并将学生添加到HashMap

if (!hashMap.containsKey(locationId)) {
    List<Student> list = new ArrayList<Student>();
    list.add(student);

    hashMap.put(locationId, list);
} else {
    hashMap.get(locationId).add(student);
}

If you want all the student with particular location details then you can use this:

如果您希望所有学生都具有特定位置的详细信息,则可以使用以下命令:

hashMap.get(locationId);

which will get you all the students with the same the location ID.

这将使您获得具有相同位置 ID 的所有学生。

回答by Omoro

You could do this:

你可以这样做:

Map<String, List<Student>> map = new HashMap<String, List<Student>>();
List<Student> studlist = new ArrayList<Student>();
studlist.add(new Student("1726", "John", "New York"));
map.put("New York", studlist);

the keys will be locations and the values list of students. So later you can get a group of students just by using:

键将是位置和学生的值列表。因此,稍后您可以通过使用以下命令来获取一组学生:

studlist = map.get("New York");

回答by Pieter

You can sort like this:

你可以这样排序:

    Collections.sort(studlist, new Comparator<Student>() {

        @Override
        public int compare(Student o1, Student o2) {
            return o1.getStud_location().compareTo(o2.getStud_location());
        }
    });

Assuming you also have the getter for location on your Student class.

假设您在 Student 类上也有位置的吸气剂。

回答by Azizi

You can use the following:

您可以使用以下内容:

Map<String, List<Student>> groupedStudents = new HashMap<String, List<Student>>();
for (Student student: studlist) {
    String key = student.stud_location;
    if (groupedStudents.get(key) == null) {
        groupedStudents.put(key, new ArrayList<Student>());
    }
    groupedStudents.get(key).add(student);
}

//print

//打印

Set<String> groupedStudentsKeySet = groupedCustomer.keySet();
for (String location: groupedStudentsKeySet) {
   List<Student> stdnts = groupedStudents.get(location);
   for (Student student : stdnts) {
        System.out.println("ID : "+student.stud_id+"\t"+"Name : "+student.stud_name+"\t"+"Location : "+student.stud_location);
    }
}

回答by sampath challa

Map<String, List<Student>> map = new HashMap<String, List<Student>>();

for (Student student : studlist) {
    String key  = student.stud_location;
    if(map.containsKey(key)){
        List<Student> list = map.get(key);
        list.add(student);

    }else{
        List<Student> list = new ArrayList<Student>();
        list.add(student);
        map.put(key, list);
    }

}

回答by Ravi Beli

Implement SQL GROUP BY Feature in Java using Comparator, comparator will compare your column data, and sort it. Basically if you keep sorted data that looks as grouped data, for example if you have same repeated column data then sort mechanism sort them keeping same data one side and then look for other data which is dissimilar data. This indirectly viewed as GROUPING of same data.

使用 Comparator 在 Java 中实现 SQL GROUP BY Feature,Comparator 将比较您的列数据,并对其进行排序。基本上,如果您保留看起来像分组数据的排序数据,例如,如果您有相同的重复列数据,则排序机制对它们进行排序,在一侧保留相同的数据,然后查找其他不同数据的数据。这间接被视为对相同数据的分组。

public class GroupByFeatureInJava {

    public static void main(String[] args) {
        ProductBean p1 = new ProductBean("P1", 20, new Date());
        ProductBean p2 = new ProductBean("P1", 30, new Date());
        ProductBean p3 = new ProductBean("P2", 20, new Date());
        ProductBean p4 = new ProductBean("P1", 20, new Date());
        ProductBean p5 = new ProductBean("P3", 60, new Date());
        ProductBean p6 = new ProductBean("P1", 20, new Date());

        List<ProductBean> list = new ArrayList<ProductBean>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        list.add(p5);
        list.add(p6);

        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            ProductBean bean = (ProductBean) iterator.next();
            System.out.println(bean);
        }
        System.out.println("******** AFTER GROUP BY PRODUCT_ID ******");
        Collections.sort(list, new ProductBean().new CompareByProductID());
        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            ProductBean bean = (ProductBean) iterator.next();
            System.out.println(bean);
        }

        System.out.println("******** AFTER GROUP BY PRICE ******");
        Collections.sort(list, new ProductBean().new CompareByProductPrice());
        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            ProductBean bean = (ProductBean) iterator.next();
            System.out.println(bean);
        }
    }
}

class ProductBean {
    String productId;
    int price;
    Date date;

    @Override
    public String toString() {
        return "ProductBean [" + productId + " " + price + " " + date + "]";
    }
    ProductBean() {
    }
    ProductBean(String productId, int price, Date date) {
        this.productId = productId;
        this.price = price;
        this.date = date;
    }
    class CompareByProductID implements Comparator<ProductBean> {
        public int compare(ProductBean p1, ProductBean p2) {
            if (p1.productId.compareTo(p2.productId) > 0) {
                return 1;
            }
            if (p1.productId.compareTo(p2.productId) < 0) {
                return -1;
            }
            // at this point all a.b,c,d are equal... so return "equal"
            return 0;
        }
        @Override
        public boolean equals(Object obj) {
            // TODO Auto-generated method stub
            return super.equals(obj);
        }
    }

    class CompareByProductPrice implements Comparator<ProductBean> {
        @Override
        public int compare(ProductBean p1, ProductBean p2) {
            // this mean the first column is tied in thee two rows
            if (p1.price > p2.price) {
                return 1;
            }
            if (p1.price < p2.price) {
                return -1;
            }
            return 0;
        }
        public boolean equals(Object obj) {
            // TODO Auto-generated method stub
            return super.equals(obj);
        }
    }

    class CompareByCreateDate implements Comparator<ProductBean> {
        @Override
        public int compare(ProductBean p1, ProductBean p2) {
            if (p1.date.after(p2.date)) {
                return 1;
            }
            if (p1.date.before(p2.date)) {
                return -1;
            }
            return 0;
        }
        @Override
        public boolean equals(Object obj) {
            // TODO Auto-generated method stub
            return super.equals(obj);
        }
    }
}

Output is here for the above ProductBean list is done GROUP BY criteria, here if you see the input data that is given list of ProductBean to Collections.sort(list, object of Comparator for your required column) This will sort based on your comparator implementation and you will be able to see the GROUPED data in below output. Hope this helps...

上面的 ProductBean 列表的输出是按照 GROUP BY 条件完成的,如果您看到输入数据,该输入数据将 ProductBean 列表提供给 Collections.sort(list, object of Comparator for your required column) 这将根据您的比较器实现进行排序您将能够在下面的输出中看到 GROUPED 数据。希望这可以帮助...

    ******** BEFORE GROUPING INPUT DATA LOOKS THIS WAY ******
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 30 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P2 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P3 60 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ******** AFTER GROUP BY PRODUCT_ID ******
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 30 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P2 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P3 60 Mon Nov 17 09:31:01 IST 2014]

    ******** AFTER GROUP BY PRICE ******
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P2 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 30 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P3 60 Mon Nov 17 09:31:01 IST 2014]

回答by Vitalii Fedorenko

In Java 8:

在 Java 8 中:

Map<String, List<Student>> studlistGrouped =
    studlist.stream().collect(Collectors.groupingBy(w -> w.stud_location));

回答by Chirag

Using Java 8

使用Java 8

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class Student {

    String stud_id;
    String stud_name;
    String stud_location;

    public String getStud_id() {
        return stud_id;
    }

    public String getStud_name() {
        return stud_name;
    }

    public String getStud_location() {
        return stud_location;
    }



    Student(String sid, String sname, String slocation) {

        this.stud_id = sid;
        this.stud_name = sname;
        this.stud_location = slocation;

    }
}

class Temp
{
    public static void main(String args[])
    {

        Stream<Student> studs = 
        Stream.of(new Student("1726", "John", "New York"),
                new Student("4321", "Max", "California"),
                new Student("2234", "Max", "Los Angeles"),
                new Student("7765", "Sam", "California"));
        Map<String, Map<Object, List<Student>>> map= studs.collect(Collectors.groupingBy(Student::getStud_name,Collectors.groupingBy(Student::getStud_location)));
                System.out.println(map);//print by name and then location
    }

}

The result will be:

结果将是:

{
    Max={
        Los Angeles=[Student@214c265e], 
        California=[Student@448139f0]
    }, 
    John={
        New York=[Student@7cca494b]
    }, 
    Sam={
        California=[Student@7ba4f24f]
    }
}

回答by jiahut

you can use guava's Multimaps

你可以使用guavaMultimaps

@Canonical
class Persion {
     String name
     Integer age
}
List<Persion> list = [
   new Persion("qianzi", 100),
   new Persion("qianzi", 99),
   new Persion("zhijia", 99)
]
println Multimaps.index(list, { Persion p -> return p.name })

it print:

它打印:

[qianzi:[com.ctcf.message.Persion(qianzi, 100),com.ctcf.message.Persion(qianzi, 88)],zhijia:[com.ctcf.message.Persion(zhijia, 99)]]

[qianzi:[com.ctcf.message.Persion(qianzi, 100),com.ctcf.message.Persion(qianzi, 88)],zhijia:[com.ctcf.message.Persion(zhijia, 99)]]

回答by TanvirChowdhury

Function<Student, List<Object>> compositKey = std ->
                Arrays.asList(std.stud_location());
        studentList.stream().collect(Collectors.groupingBy(compositKey, Collectors.toList()));

If you want to add multiple objects for group by you can simply add the object in compositKeymethod separating by a comma:

如果要为 group by 添加多个对象,只需在compositKey方法中添加对象,以逗号分隔:

Function<Student, List<Object>> compositKey = std ->
                Arrays.asList(std.stud_location(),std.stud_name());
        studentList.stream().collect(Collectors.groupingBy(compositKey, Collectors.toList()));