Згрупуйте список об'єктів за атрибутом: Java


97

Мені потрібно згрупувати список об'єктів (Student) за допомогою атрибута (Location) конкретного об'єкта, код такий, як показано нижче,

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;

    }
}

Будь ласка, підкажіть мені чистий спосіб це зробити.


2
Хеш-карта з розташуванням як ключем та списком студентів як значенням.
Оморо

Чи може сортування за місцем розташування вирішити вашу проблему, чи є щось інше?
Воєначальник

Спробуйте скористатись компаратором та сортуйте за місцем розташування.
pshemek

1
@Warlord Так, але йдучи далі, якщо мені потрібна інформація, наприклад, Підрахунок студентів за
місцем

@Omoro Будь ласка, можете ви дати мені підказку за кодом, я не настільки знайомий з хеш-картами
Ділукшан Махендра

Відповіді:


131

Це додасть об’єкт студентів до ключа HashMapз locationIDяк.

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

Повторіть цей код і додайте студентів до HashMap:

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

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

Якщо вам потрібні всі студенти з конкретними даними про місцезнаходження, ви можете використовувати це:

hashMap.get(locationId);

що дасть вам всім студентам однаковий ідентифікатор місцезнаходження.


4
Ви оголосили Список об'єктів розташування, а в наступному рядку додаєте об'єкт Студента до попереднього списку, що повинно викликати помилку.
OJVM

hashMap.get () повертає null, коли hashMap.contanisKey () повертає false. Ви можете зберегти виклик методу containsKey (), якщо спочатку викликаєте hashMap.get (), зберігаєте результат у локальній змінній і перевіряєте, чи є цей локальний змінний нульовим
Естеве

248

У Java 8:

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

Це тому, що в Studentкласі stud_locationвказано як Friendly. Доступ може мати лише Studentклас та будь-який клас, визначений у тому самому пакеті . Якщо ви ставите замість , це має спрацювати. Або ви можете визначити функцію отримання. Більше інформації в cs.princeton.edu/courses/archive/spr96/cs333/java/tutorial/java/…Studentstud_locationpublic String stud_location;String stud_location;
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

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
    }

}

Результатом буде:

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

Цю відповідь можна покращити, дотримуючись того самого прикладу, що і питання. Також результат не збігається з бажаним результатом, запитаним у питанні.
Пім Хазебрук,

5

Групування Java 8 від Collector

Можливо, вже пізно, але я люблю поділитися вдосконаленою ідеєю щодо цієї проблеми. В основному це те саме, що і відповідь @Vitalii Fedorenko, але більш зручний для роздумів.

Ви можете просто використовувати Collectors.groupingBy(), передавши логіку групування як параметр функції, і ви отримаєте розділений список із зіставленням ключових параметрів. Зверніть увагу, що використання Optionalвикористовується, щоб уникнути небажаного NPE, коли наданий список є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));
}

Тепер ви можете згрупувати будь-що з цим. Для випадку використання тут у питанні

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

Можливо, ви хотіли б ознайомитися з цим також Посібником із Java 8 groupingBy Collector


4

Ви можете використовувати наступне:

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

// друк

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

Впровадьте функцію SQL GROUP BY у Java за допомогою компаратора, компаратор порівняє дані ваших стовпців та відсортує їх. В основному, якщо ви зберігаєте відсортовані дані, які виглядають як згруповані дані, наприклад, якщо у вас однакові дані повторюваних стовпців, тоді механізм сортування сортує їх, зберігаючи однакові дані на одній стороні, а потім шукає інші дані, що відрізняються від даних. Це побічно розглядається як ГРУПУВАННЯ тих самих даних.

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

Вихідні дані для вищезазначеного списку ProductBean виконуються за критеріями GROUP BY, тут, якщо ви бачите вхідні дані, які надаються списку ProductBean для Collections.sort (список, об’єкт компаратора для потрібного стовпця) Це буде відсортовано на основі вашої реалізації компаратора і ви зможете побачити ЗГРУПОВАНІ дані в нижченаведеному виведенні. Сподіваюся, це допомагає ...

    ******** ПЕРЕД ГРУПУВАННЯМ ВХІДНИХ ДАНИХ ПОГЛЯДАЄ ЦЕ ШАГ ******
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P1 30 пн. 17 листопада 09:31:01, IST 2014]
    ProductBean [P2 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P3 60, пн. 17 листопада 09:31:01, IST 2014]
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ******** ПІСЛЯ ГРУПИ ЗА ІДЕНТИФІКАТОРОМ _ ******
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P1 30 пн. 17 листопада 09:31:01, IST 2014]
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P2 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P3 60, пн. 17 листопада 09:31:01, IST 2014]

    ******** ПІСЛЯ ГРУПИ ЗА ЦІНОЮ ******
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P2 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P1 20 пн. Листопада 17 09:31:01, IST 2014]
    ProductBean [P1 30 пн. 17 листопада 09:31:01, IST 2014]
    ProductBean [P3 60, пн. 17 листопада 09:31:01, IST 2014]


1
Привіт, будь ласка, не публікуйте одну і ту ж відповідь кілька разів, і, будь ласка, не публікуйте необроблений код без пояснення того, як він працює та як він вирішує проблему у вищезазначеному питанні.
мат

Вибачте, друже, під час вставки коду сталася помилка, оскільки це могло статися кілька разів. Я відредагував пояснення того, що розмістив. Сподіваюся, це зараз виглядає добре ???
Раві Белі,

Я чогось пропускаю або цей код сортує, а не групує за полем? Я бачу товари, відсортовані за ідентифікатором, потім за ціною
Фундер

0

Ви можете сортувати так:

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

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

Припускаючи, що у вас також є геттер для розташування вашого класу Student.


3
Чому сортувати? Проблема полягає в групуванні елементів!
Санкалп,

0

Ви можете зробити це:

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

ключі будуть місцями та списком значень учнів. Тож згодом ви зможете отримати групу студентів, просто використовуючи:

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

0

Ви можете використовувати 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 })

це друк:

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

Якщо ви хочете додати кілька об’єктів для групи за допомогою, ви можете просто додати об’єкт у compositKeyметод, розділяючи його комами:

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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.