Kelompokkan daftar objek menurut atribut

103

Saya perlu mengelompokkan daftar objek ( Student) menggunakan atribut ( Location) dari objek tertentu. Kodenya seperti di bawah ini:

public class Grouping {
    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"));

    }
}

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

Tolong sarankan saya cara yang bersih untuk melakukannya.

Dilukshan Mahendra
sumber
2
Sebuah peta hash dengan lokasi sebagai kuncinya dan daftar siswa sebagai nilai.
Omoro
Apakah menyortir menurut lokasi akan menyelesaikan masalah Anda, atau adakah hal lain?
Warlord
Coba gunakan Comparator dan urutkan berdasarkan lokasi.
pshemek
1
@Warlord Ya, Tapi melangkah lebih jauh jika saya perlu mendapatkan informasi seperti, Siswa menghitung berdasarkan Lokasi lebih baik jika saya bisa mengelompokkannya
Dilukshan Mahendra
@Omoro Tolong bisakah Anda memberi saya petunjuk dengan kode, saya tidak begitu akrab dengan Hashmaps
Dilukshan Mahendra

Jawaban:

134

Ini akan menambahkan objek siswa ke HashMapdengan locationIDsebagai kunci.

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

Iterasi kode ini dan tambahkan siswa ke HashMap:

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

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

Jika Anda menginginkan semua siswa dengan detail lokasi tertentu maka Anda dapat menggunakan ini:

hashMap.get(locationId);

yang akan memberi Anda semua siswa dengan ID lokasi yang sama.

Dileep
sumber
4
Anda mendeklarasikan objek List of Location dan di baris berikutnya Anda menambahkan objek Student ke daftar sebelumnya yang seharusnya menimbulkan kesalahan.
OJVM
hashMap.get () mengembalikan null ketika hashMap.contanisKey () mengembalikan false. Anda bisa menyimpan panggilan ke metode containsKey () jika Anda memanggil hashMap.get () pertama, menyimpan hasil di var lokal, dan memeriksa apakah var lokal ini null
Esteve
264

Di Jawa 8:

Map<String, List<Student>> studlistGrouped =
    studlist.stream().collect(Collectors.groupingBy(w -> w.stud_location));
Vitalii Fedorenko
sumber
Itu karena di Studentkelas stud_locationditetapkan sebagai Ramah. Hanya Studentkelas dan kelas apa pun yang ditentukan dalam paket yang sama yang Studentdapat mengakses stud_location. Jika Anda meletakkan public String stud_location;alih-alih String stud_location;, ini harus bekerja. Atau Anda dapat menentukan fungsi pengambil. Info lebih lanjut di cs.princeton.edu/courses/archive/spr96/cs333/java/tutorial/java/…
Eranga 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);
    }

}
sampath challa
sumber
8

Menggunakan 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
    }

}

Hasilnya adalah:

{
    Max={
        Los Angeles=[Student@214c265e], 
        California=[Student@448139f0]
    }, 
    John={
        New York=[Student@7cca494b]
    }, 
    Sam={
        California=[Student@7ba4f24f]
    }
}
Chirag
sumber
Jawaban ini dapat ditingkatkan dengan tetap berpegang pada contoh yang sama seperti pertanyaan. Juga hasilnya tidak sesuai dengan keluaran yang diinginkan yang diminta dalam soal.
Pim Hazebroek
6

Pengelompokan Java 8 Oleh Kolektor

Mungkin sudah terlambat tetapi saya ingin berbagi ide yang lebih baik untuk masalah ini. Ini pada dasarnya sama dengan jawaban @Vitalii Fedorenko tetapi lebih mudah untuk dimainkan.

Anda cukup menggunakan Collectors.groupingBy()dengan melewatkan logika pengelompokan sebagai parameter fungsi dan Anda akan mendapatkan daftar yang dipisahkan dengan pemetaan parameter kunci. Perhatikan bahwa penggunaan Optionaldigunakan untuk menghindari NPE yang tidak diinginkan saat daftar yang disediakannull

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

Sekarang Anda dapat mengelompokkan apa pun dengan ini. Untuk kasus penggunaan di sini, di pertanyaan

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

Mungkin Anda juga ingin melihat Panduan untuk Java 8 groupingBy Collector ini

Shafin Mahmud
sumber
4

Anda dapat menggunakan berikut ini:

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

//mencetak

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);
    }
}
Azizi
sumber
4

Menerapkan Fitur SQL GROUP BY di Java menggunakan Comparator, pembanding akan membandingkan data kolom Anda, dan mengurutkannya. Pada dasarnya jika Anda menyimpan data yang diurutkan yang terlihat seperti data yang dikelompokkan, misalnya jika Anda memiliki data kolom berulang yang sama maka mekanisme pengurutan menyortirnya dengan menyimpan data yang sama di satu sisi dan kemudian mencari data lain yang merupakan data yang berbeda. Ini secara tidak langsung dipandang sebagai PENGELOMPOKAN data yang sama.

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 di sini untuk daftar ProductBean di atas dilakukan dengan kriteria GROUP BY, di sini jika Anda melihat data input yang diberikan daftar ProductBean ke Collections.sort (daftar, objek Pembanding untuk kolom yang diperlukan) Ini akan mengurutkan berdasarkan implementasi komparator Anda dan Anda akan dapat melihat data yang DIKELOMPOKKAN di bawah ini. Semoga ini membantu...

    ******** SEBELUM MENGELOMPOKKAN DATA MASUKAN TERLIHAT CARA INI ******
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 30 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P2 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P3 60 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ******** SETELAH GRUP OLEH PRODUCT_ID ******
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 30 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P2 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P3 60 Sen, 17 Nov 09:31:01 IST 2014]

    ******** SETELAH KELOMPOK BERDASARKAN HARGA ******
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P2 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 20 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P1 30 Sen, 17 Nov 09:31:01 IST 2014]
    ProductBean [P3 60 Sen, 17 Nov 09:31:01 IST 2014]

Ravi Beli
sumber
1
Hai, tolong jangan memposting jawaban yang sama beberapa kali, dan tolong jangan memposting kode mentah tanpa penjelasan tentang cara kerjanya dan cara menyelesaikan masalah dalam pertanyaan di atas.
Mat
Maaf sobat, ada kesalahan saat menempelkan kode, karena mungkin sudah berkali-kali. Saya telah mengedit penjelasan untuk apa yang saya posting. Berharap itu terlihat baik-baik saja sekarang ???
Ravi Beli
Saya kehilangan sesuatu atau kode ini sedang diurutkan, bukan dikelompokkan berdasarkan bidang? Saya melihat produk diurutkan berdasarkan ID, lalu berdasarkan Harga
funder7
1
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
}
Soudipta Dutta
sumber
0

Anda bisa mengurutkan seperti ini:

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

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

Dengan asumsi Anda juga memiliki pengambil lokasi di kelas Siswa Anda.

Pieter
sumber
5
Mengapa Sortir? Masalahnya adalah mengelompokkan elemen!
Sankalp
0

Anda bisa melakukan ini:

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

kuncinya adalah lokasi dan daftar nilai siswa. Jadi nanti Anda bisa mendapatkan sekelompok siswa hanya dengan menggunakan:

studlist = map.get("New York");
Omoro
sumber
0

Anda dapat menggunakan 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 })

itu mencetak:

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

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

Jika Anda ingin menambahkan beberapa objek untuk dikelompokkan dengan Anda cukup menambahkan objek dalam compositKeymetode memisahkan dengan koma:

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