Bir nesne listesini bir özniteliğe göre gruplandırma


103

Belirli bir nesnenin Studentbir niteliğini ( Location) kullanarak bir nesne listesini ( ) gruplamam gerekiyor . Kod aşağıdaki gibidir:

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

Lütfen bana bunu yapmanın temiz bir yolunu önerin.


2
Anahtar olarak konum ve öğrencilerin değer olarak listelediği bir hashmap.
Omoro

Konuma göre sıralama sorununuzu çözer mi yoksa başka bir şey mi var?
Warlord

Karşılaştırıcıyı kullanmayı deneyin ve konuma göre sıralayın.
pshemek

1
@Warlord Evet, ama daha da ileri gidersem, Yere göre Öğrenci sayısı gibi bilgileri gruplandırabilirsem daha iyi olur
Dilukshan Mahendra

@Omoro Lütfen bana kodla bir ipucu verebilir misiniz, Hashmaps'e pek aşina değilim
Dilukshan Mahendra

Yanıtlar:


133

Bu, öğrencilerin itirazını anahtar olarak HashMapile ekleyecektir locationID.

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

Bu kodu yineleyin ve öğrencileri şuraya ekleyin HashMap:

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

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

Tüm öğrencinin belirli konum ayrıntılarına sahip olmasını istiyorsanız, bunu kullanabilirsiniz:

hashMap.get(locationId);

bu size tüm öğrencilerin aynı konum kimliğine sahip olmasını sağlayacaktır.


4
Bir Konum nesneleri Listesi bildirdiniz ve sonraki satırda, önceki listeye bir hata atması gereken bir Öğrenci nesnesi eklediniz.
OJVM

hashMap.get (), hashMap.contanisKey () false döndürdüğünde null döndürür. İlk hashMap.get () öğesini çağırırsanız, sonucu yerel bir var içinde depolarsanız ve bu yerel değişkenin boş olup olmadığını kontrol ederseniz, çağrıyı containsKey () yöntemine kaydedebilirsiniz
Esteve

263

Java 8'de:

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

Bunun nedeni, Studentsınıfta stud_locationDost olarak belirtilmesidir. Yalnızca Studentsınıf ve aynı paket içinde tanımlanan herhangi bir sınıf Studenterişebilir stud_location. public String stud_location;Bunun yerine koyarsanız String stud_location;, bu çalışmalıdır. Veya bir alıcı işlevi tanımlayabilirsiniz. Daha fazla bilgi 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);
    }

}

8

Java 8'i kullanma

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
    }

}

Sonuç şu şekilde olacaktır:

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

Bu cevap, soru ile aynı örneğe sadık kalınarak geliştirilebilir. Ayrıca sonuç soruda istenen çıktı ile uyuşmuyor.
Pim Hazebroek

6

Collector ile Java 8 gruplama

Muhtemelen geç oldu ama bu sorunla ilgili geliştirilmiş bir fikir paylaşmaktan hoşlanıyorum. Bu, temelde @Vitalii Fedorenko'nun cevabıyla aynı, ancak oynaması daha kolay.

Collectors.groupingBy()Gruplama mantığını işlev parametresi olarak geçirerek kullanabilirsiniz ve anahtar parametre eşlemesiyle bölünmüş listeyi elde edersiniz. OptionalSağlanan liste olduğunda istenmeyen NPE'yi önlemek için kullanıldığını unutmayın.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));
}

Artık bununla istediğiniz şekilde gruplayabilirsiniz . Buradaki soruda kullanım örneği için

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

Belki bu da Java 8 gruplama Kılavuzu'na da bakmak istersiniz.


4

Aşağıdakileri kullanabilirsiniz:

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

//Yazdır

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

Karşılaştırıcı kullanarak Java'da SQL GROUP BY Özelliğini uygulayın, karşılaştırıcı sütun verilerinizi karşılaştıracak ve sıralayacaktır. Temel olarak, gruplanmış veriler olarak görünen sıralı verileri tutarsanız, örneğin aynı tekrarlanan sütun verileriniz varsa, mekanizmayı sıralayın, aynı verileri bir tarafta tutun ve sonra farklı veriler olan diğer verileri arayın. Bu, dolaylı olarak aynı verilerin GRUPLANDIRILMASI olarak görülmüştür.

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

Yukarıdaki ProductBean listesi için çıktı burada yapılır GROUP BY ölçütü yapılır, burada ProductBean'ın Collections.sort listesine verilen giriş verilerini görürseniz (liste, gerekli sütun için Karşılaştırıcı nesnesi) Bu, karşılaştırıcı uygulamanıza göre sıralayacaktır. ve GRUPLANDIRILMIŞ verileri aşağıdaki çıktıda görebileceksiniz. Bu yardımcı olur umarım...

    ******** GİRİŞ VERİLERİNİ GRUPLAMADAN ÖNCE BU ŞEKİLDE GÖRÜNÜR ******
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P1 30 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P2 20 Kasım 17 Pzt 09:31:01 IST 2014]
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P3 60 17 Kasım Pazartesi 09:31:01 IST 2014]
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ******** ÜRÜN KİMLİĞİNE GÖRE GRUPLAMA SONRASI ******
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P1 30 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P2 20 Kasım 17 Pzt 09:31:01 IST 2014]
    ProductBean [P3 60 17 Kasım Pazartesi 09:31:01 IST 2014]

    ******** FİYATA GÖRE GRUP SONRASI ******
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P2 20 Kasım 17 Pzt 09:31:01 IST 2014]
    ProductBean [P1 20 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P1 30 Kasım 17 Pazartesi 09:31:01 IST 2014]
    ProductBean [P3 60 17 Kasım Pazartesi 09:31:01 IST 2014]


1
Merhaba, lütfen aynı cevabı birden çok kez göndermeyin ve lütfen ham kodu nasıl çalıştığı ve yukarıdaki soruda sorunu nasıl çözdüğü hakkında açıklama yapmadan göndermeyin.
Mat

Üzgünüm dostum, kodu yapıştırırken bir hata oldu, çünkü birden çok kez olabilirdi. Yayınladığım şeyin açıklamasını düzenledim. Umarım şimdi iyi görünüyor ???
Ravi Beli

Bir şey eksik mi yoksa bu kod bir alana göre gruplamak yerine mi sıralanıyor? Kimliğe ve ardından Fiyata göre sıralanmış ürünleri görüyorum
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
}

0

Şu şekilde sıralayabilirsiniz:

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

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

Öğrenci sınıfınızda konum için alıcıya da sahip olduğunuzu varsayarsak.


5
Neden Sırala? Sorun, öğeleri gruplamaktır!
Sankalp

0

Bunu yapabilirsin:

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

anahtarlar öğrencilerin yerleri ve değerler listesi olacaktır. Böylece daha sonra yalnızca şunları kullanarak bir grup öğrenci edinebilirsiniz:

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

0

guava's kullanabilirsinizMultimaps

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

yazdır:

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

Gruplama için birden çok nesne eklemek istiyorsanız, nesneyi compositKeyvirgülle ayırarak yöntemle ekleyebilirsiniz :

Function<Student, List<Object>> compositKey = std ->
                Arrays.asList(std.stud_location(),std.stud_name());
        studentList.stream().collect(Collectors.groupingBy(compositKey, Collectors.toList()));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.