Nhóm danh sách các đối tượng theo một thuộc tính: Java


97

Tôi cần nhóm một danh sách các đối tượng (Sinh viên) bằng cách sử dụng một thuộc tính (Vị trí) của đối tượng cụ thể, mã như dưới đây,

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;

    }
}

Vui lòng đề xuất cho tôi một cách sạch sẽ để làm điều đó.


2
Một bản đồ băm với vị trí là khóa và danh sách sinh viên là giá trị.
Omoro

Việc sắp xếp theo vị trí có giải quyết được vấn đề của bạn không hay còn điều gì khác?
Warlord

Hãy thử sử dụng Bộ so sánh và sắp xếp theo vị trí.
pshemek

1
@Warlord Vâng, Nhưng đi xa hơn nếu tôi cần thu thập thông tin như thế nào, số lượng sinh viên theo Địa điểm tốt hơn nếu tôi có thể làm cho nó nhóm
Dilukshan Mahendra

@Omoro Làm ơn bạn có thể cho tôi một manh mối bằng mã, Tôi không quá quen thuộc với Hashmaps
Dilukshan Mahendra

Câu trả lời:


131

Điều này sẽ thêm đối tượng sinh viên vào khóa HashMapwith locationIDas.

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

Lặp lại mã này và thêm sinh viên vào HashMap:

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

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

Nếu bạn muốn tất cả sinh viên có chi tiết vị trí cụ thể thì bạn có thể sử dụng cái này:

hashMap.get(locationId);

điều này sẽ giúp bạn nhận được tất cả các sinh viên có cùng ID vị trí.


4
Bạn đã khai báo Danh sách các đối tượng Vị trí và trong dòng tiếp theo, bạn thêm một đối tượng Sinh viên vào danh sách trước đó sẽ gây ra lỗi.
OJVM

hashMap.get () trả về null khi hashMap.contanisKey () trả về false. Bạn có thể lưu cuộc gọi đến phương thức containsKey () nếu bạn gọi hashMap.get () đầu tiên, lưu trữ kết quả trong một var cục bộ và kiểm tra xem var cục bộ này có phải là null hay không
Esteve

248

Trong Java 8:

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

Đó là bởi vì trong Studentlớp stud_locationđược chỉ định là Thân thiện. Chỉ Studentlớp và bất kỳ lớp nào được định nghĩa trong cùng một gói mới Studentcó thể truy cập stud_location. Nếu bạn đặt public String stud_location;thay vì String stud_location;, điều này sẽ hoạt động. Hoặc bạn có thể xác định một hàm getter. Thông tin thêm trong cs.princeton.edu/courses/archive/spr96/cs333/java/tutorial/java/…
Heshan

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

}

8

Sử dụng 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
    }

}

Kết quả sẽ là:

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

Câu trả lời này có thể được cải thiện bằng cách bám vào ví dụ tương tự như câu hỏi. Ngoài ra, kết quả không khớp với đầu ra mong muốn được yêu cầu trong câu hỏi.
Pim Hazebroek

5

Phân nhóm Java 8By Collector

Có lẽ đã muộn nhưng tôi muốn chia sẻ một ý tưởng cải tiến cho vấn đề này. Về cơ bản, câu trả lời này giống với câu trả lời của @Vitalii Fedorenko nhưng dễ thực hiện hơn.

Bạn chỉ có thể sử dụng Collectors.groupingBy()bằng cách chuyển logic nhóm làm tham số hàm và bạn sẽ nhận được danh sách được chia nhỏ với ánh xạ tham số chính. Lưu ý rằng việc sử dụng Optionalđược sử dụng để tránh NPE không mong muốn khi danh sách được cung cấp là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));
}

Bây giờ bạn có thể nhómBy bất cứ thứ gì với cái này. Đối với trường hợp sử dụng ở đây trong câu hỏi

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

Có thể bạn cũng muốn xem xét phần này Hướng dẫn cách nhóm trong Java 8


4

Bạn có thể sử dụng như sau:

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

//in

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

4

Triển khai Tính năng NHÓM BẰNG SQL trong Java bằng Bộ so sánh, bộ so sánh sẽ so sánh dữ liệu cột của bạn và sắp xếp nó. Về cơ bản, nếu bạn giữ dữ liệu được sắp xếp giống như dữ liệu được nhóm lại, ví dụ: nếu bạn có cùng một dữ liệu cột lặp đi lặp lại thì cơ chế sắp xếp sẽ sắp xếp chúng giữ cùng một dữ liệu ở một phía và sau đó tìm kiếm dữ liệu khác là dữ liệu không giống nhau. Điều này gián tiếp được xem như NHÓM của cùng một dữ liệu.

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

Đầu ra ở đây cho danh sách ProductBean ở trên được thực hiện theo tiêu chí GROUP BY, tại đây nếu bạn thấy dữ liệu đầu vào được cung cấp danh sách ProductBean thành Collections.sort (danh sách, đối tượng của Comparator cho cột bắt buộc của bạn). Điều này sẽ sắp xếp dựa trên việc triển khai trình so sánh của bạn và bạn sẽ có thể xem dữ liệu GROUPED ở đầu ra bên dưới. Hi vọng điêu nay co ich...

    ******** TRƯỚC KHI NHÓM DỮ LIỆU ĐẦU VÀO NHÓM NHÓM CÁCH NÀY ******
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P1 30 Thứ Hai, ngày 17 tháng 11, 09:31:01 IST 2014]
    ProductBean [P2 20 Thứ Hai, ngày 17 tháng 11, 09:31:01 IST 2014]
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P3 60 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ******** SAU NHÓM BẰNG PRODUCT_ID ******
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P1 30 Thứ Hai, ngày 17 tháng 11, 09:31:01 IST 2014]
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P2 20 Thứ Hai, ngày 17 tháng 11, 09:31:01 IST 2014]
    ProductBean [P3 60 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]

    ******** NHÓM SAU THEO GIÁ ******
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P2 20 Thứ Hai, ngày 17 tháng 11, 09:31:01 IST 2014]
    ProductBean [P1 20 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]
    ProductBean [P1 30 Thứ Hai, ngày 17 tháng 11, 09:31:01 IST 2014]
    ProductBean [P3 60 Thứ Hai, ngày 17 tháng 11 09:31:01 IST 2014]


1
Xin chào, vui lòng không đăng cùng một câu trả lời nhiều lần và vui lòng không đăng mã thô mà không có lời giải thích về cách hoạt động và cách nó giải quyết vấn đề trong câu hỏi ở trên.
Mat

Xin lỗi anh bạn, đã xảy ra lỗi khi dán mã, vì nó có thể đã trở thành nhiều lần. Tôi đã chỉnh sửa lời giải thích cho những gì tôi đã đăng. Hy vọng rằng có vẻ ổn bây giờ ???
Ravi Beli

Tôi thiếu thứ gì đó hoặc mã này đang sắp xếp thay vì nhóm theo trường? Tôi thấy các sản phẩm được sắp xếp theo ID, sau đó theo Giá
Nhà tài trợ

0

Bạn có thể sắp xếp như thế này:

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

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

Giả sử bạn cũng có bộ định vị cho vị trí trên lớp Sinh viên của mình.


3
Tại sao lại sắp xếp? Vấn đề là nhóm các phần tử!
Sankalp

0

Bạn có thể làm điều này:

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

các khóa sẽ là vị trí và danh sách giá trị của học sinh. Vì vậy, sau này bạn có thể có được một nhóm sinh viên chỉ bằng cách sử dụng:

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

0

bạn có thể sử dụng guava'sMultimaps

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

nó in:

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


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

Nếu bạn muốn thêm nhiều đối tượng cho nhóm theo nhóm, bạn có thể chỉ cần thêm đối tượng trong compositKeyphương thức phân tách bằng dấu phẩy:

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

0
public class Test9 {

    static class Student {

        String stud_id;
        String stud_name;
        String stud_location;

        public Student(String stud_id, String stud_name, String stud_location) {
            super();
            this.stud_id = stud_id;
            this.stud_name = stud_name;
            this.stud_location = stud_location;
        }

        public String getStud_id() {
            return stud_id;
        }

        public void setStud_id(String stud_id) {
            this.stud_id = stud_id;
        }

        public String getStud_name() {
            return stud_name;
        }

        public void setStud_name(String stud_name) {
            this.stud_name = stud_name;
        }

        public String getStud_location() {
            return stud_location;
        }

        public void setStud_location(String stud_location) {
            this.stud_location = stud_location;
        }

        @Override
        public String toString() {
            return " [stud_id=" + stud_id + ", stud_name=" + stud_name + "]";
        }

    }

    public static void main(String[] args) {

        List<Student> list = new ArrayList<Student>();
        list.add(new Student("1726", "John Easton", "Lancaster"));
        list.add(new Student("4321", "Max Carrados", "London"));
        list.add(new Student("2234", "Andrew Lewis", "Lancaster"));
        list.add(new Student("5223", "Michael Benson", "Leeds"));
        list.add(new Student("5225", "Sanath Jayasuriya", "Leeds"));
        list.add(new Student("7765", "Samuael Vatican", "California"));
        list.add(new Student("3442", "Mark Farley", "Ladykirk"));
        list.add(new Student("3443", "Alex Stuart", "Ladykirk"));
        list.add(new Student("4321", "Michael Stuart", "California"));

        Map<String, List<Student>> map1  =

                list
                .stream()

            .sorted(Comparator.comparing(Student::getStud_id)
                    .thenComparing(Student::getStud_name)
                    .thenComparing(Student::getStud_location)
                    )

                .collect(Collectors.groupingBy(

                ch -> ch.stud_location

        ));

        System.out.println(map1);

/*
  Output :

{Ladykirk=[ [stud_id=3442, stud_name=Mark Farley], 
 [stud_id=3443, stud_name=Alex Stuart]], 

 Leeds=[ [stud_id=5223, stud_name=Michael Benson],  
 [stud_id=5225, stud_name=Sanath Jayasuriya]],


  London=[ [stud_id=4321, stud_name=Max Carrados]],


   Lancaster=[ [stud_id=1726, stud_name=John Easton],  

   [stud_id=2234, stud_name=Andrew Lewis]], 


   California=[ [stud_id=4321, stud_name=Michael Stuart],  
   [stud_id=7765, stud_name=Samuael Vatican]]}
*/


    }// main
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.