속성별로 객체 목록 그룹화 : Java


97

특정 개체의 속성 (위치)을 사용하여 개체 (학생) 목록을 그룹화해야합니다. 코드는 다음과 같습니다.

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
위치가 키로 포함 된 해시 맵과 학생이 값으로 나열됩니다.
Omoro 2014

위치별로 정렬하면 문제가 해결됩니까, 아니면 다른 것이 있습니까?
Warlord

비교기를 사용하고 위치별로 정렬 해보십시오.
pshemek

1
@Warlord 예,하지만 정보가 필요하면 더 나아가, 그룹화 할 수 있다면 위치 별 학생 수를 더 잘 계산합니다
Dilukshan Mahendra

@Omoro 제발 당신이 나에게 코드로 단서를 줄 수 있습니다, Im Hashmaps에 그렇게 익숙하지 않습니다
Dilukshan Mahendra

답변:


131

그러면 HashMapwith 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);

동일한 위치 ID를 가진 모든 학생을 얻을 수 있습니다.


4
위치 개체 목록을 선언하고 다음 줄에서 오류가 발생하는 이전 목록에 학생 개체를 추가합니다.
OJVM

hashMap.contanisKey ()가 false를 반환하면 hashMap.get ()은 null을 반환합니다. 이 지역의 VAR가 null의 경우 로컬 VAR 먼저 hashMap.get (), 저장 결과를 호출하는 경우 containsKey () 메소드에 대한 호출을 저장하고 확인할 수 있습니다
에스테

248

Java 8에서

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

in Studentclass stud_location가 Friendly로 지정 되기 때문입니다 . Student클래스 및의 동일한 패키지에 정의 된 모든 클래스 만에 Student액세스 할 수 있습니다 stud_location. public String stud_location;대신 넣으면 String stud_location;작동합니다. 또는 getter 함수를 정의 할 수 있습니다. 더 많은 정보를 원하시면 cs.princeton.edu/courses/archive/spr96/cs333/java/tutorial/java/...
Eranga 헤샨

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

이 답변은 질문과 동일한 예를 고수함으로써 개선 될 수 있습니다. 또한 결과가 질문에서 요청한 원하는 출력과 일치하지 않습니다.
Pim Hazebroek

5

Java 8 그룹화 By Collector

아마도 늦었지만이 문제에 대한 개선 된 아이디어를 공유하고 싶습니다. 이것은 기본적으로 @Vitalii Fedorenko의 답변과 동일하지만 더 쉽게 놀 수 있습니다.

Collectors.groupingBy()그룹화 논리를 함수 매개 변수로 전달하여를 사용할 수 있으며 키 매개 변수 매핑이있는 분할 된 목록을 얻을 수 있습니다. Optional제공된 목록이 다음과 같을 때 원치 않는 NPE를 방지하기 위해 using 이 사용됩니다.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));
}

이제 이것으로 무엇이든 groupBy 할 수 있습니다 . 여기 질문의 사용 사례

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

Comparator를 사용하여 Java에서 SQL GROUP BY Feature를 구현하면 comparator가 열 데이터를 비교하고 정렬합니다. 기본적으로 그룹화 된 데이터처럼 보이는 정렬 된 데이터를 유지하는 경우, 예를 들어 동일한 반복 열 데이터가있는 경우 정렬 메커니즘은 동일한 데이터를 유지하면서 정렬 한 다음 다른 데이터 인 다른 데이터를 찾습니다. 이것은 간접적으로 동일한 데이터의 GROUPING으로 간주됩니다.

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 (list, object of Comparator for your required column)에 제공된 입력 데이터가 표시되면 비교기 구현을 기반으로 정렬됩니다. 아래 출력에서 ​​GROUPED 데이터를 볼 수 있습니다. 도움이 되었기를 바랍니다...

    ******** 입력 데이터를 그룹화하기 전에이 방식으로 보입니다 ******
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 30 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P2 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P3 60 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ******** PRODUCT_ID 별 그룹화 후 ******
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 30 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P2 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P3 60 Mon Nov 17 09:31:01 IST 2014]

    ******** 가격 별 그룹화 후 ******
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P2 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 20 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P1 30 Mon Nov 17 09:31:01 IST 2014]
    ProductBean [P3 60 Mon Nov 17 09:31:01 IST 2014]


1
안녕하세요, 동일한 답변을 여러 번 게시하지 마시고 위의 질문에서 어떻게 작동하는지, 어떻게 문제를 해결하는지에 대한 설명없이 원시 코드를 게시하지 마십시오.
Mat

죄송합니다. 코드를 여러 번 붙여 넣는 데 실수가있었습니다. 게시 한 내용에 대한 설명을 편집했습니다. 이제 괜찮아 보이는 희망 ???
Ravi Beli

뭔가 누락되었거나이 코드가 필드별로 그룹화하는 대신 정렬됩니까? 제품이 ID별로 정렬 된 다음 가격별로 정렬되어 있습니다.
Funder

0

다음과 같이 정렬 할 수 있습니다.

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

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

Student 클래스의 위치에 대한 getter도 있다고 가정합니다.


3
왜 정렬? 문제는 요소를 그룹화하는 것입니다!
Sankalp

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'들Multimaps

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

group by에 여러 개체를 추가하려면 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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.