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

Dil*_*dra 83 java grouping list

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

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;

    }
}
Run Code Online (Sandbox Code Playgroud)

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

Vit*_*nko 216

在Java 8中:

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


Dil*_*eep 111

这会将student对象添加到HashMapwith locationID作为键.

HashMap<Integer, List<Student>> hashMap = new HashMap<Integer, List<Student>>();
Run Code Online (Sandbox Code Playgroud)

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

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

    hashMap.put(locationId, list);
} else {
    hashMap.get(locationId).add(student);
}
Run Code Online (Sandbox Code Playgroud)

如果您希望所有学生都有特定的位置详细信息,那么您可以使用:

hashMap.get(locationId);
Run Code Online (Sandbox Code Playgroud)

这将使所有学生获得相同的位置ID.

  • 您声明了一个Location对象List,并在下一行中将Student对象添加到上一个列表中,该对象应该抛出错误. (4认同)

sam*_*lla 29

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);
    }

}
Run Code Online (Sandbox Code Playgroud)


Sha*_*mud 9

Java 8 groupingBy 收集器

可能已经晚了,但我想分享一个对这个问题的改进想法。这与@Vitalii Fedorenko 的答案基本相同,但更容易玩。

您可以Collectors.groupingBy()通过将分组逻辑作为函数参数传递来使用,您将获得带有关键参数映射的拆分列表。请注意,Optional当提供的列表为null

public static <E, K> Map<K, List<E>> groupBy(List<E> list, Function<E, K> keyFunction) {
    return Optional.ofNullable(list)
            .orElseGet(ArrayList::new)
            .stream()
            .collect(Collectors.groupingBy(keyFunction));
}
Run Code Online (Sandbox Code Playgroud)

现在你可以用这个groupBy任何东西。对于问题中的用例

Map<String, List<Student>> map = groupBy(studlist, Student::getLocation);

也许你想看看这个Java 8 groupingBy Collector 指南


Chi*_*rag 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
    }

}
Run Code Online (Sandbox Code Playgroud)

结果将是:

{
    Max={
        Los Angeles=[Student@214c265e], 
        California=[Student@448139f0]
    }, 
    John={
        New York=[Student@7cca494b]
    }, 
    Sam={
        California=[Student@7ba4f24f]
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 通过坚持与问题相同的例子可以改进这个答案。此外,结果与问题中请求的所需输出不匹配。 (2认同)

Azi*_*izi 5

您可以使用以下内容:

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);
}
Run Code Online (Sandbox Code Playgroud)

//打印

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);
    }
}
Run Code Online (Sandbox Code Playgroud)