[JAVA] 정리/클래스(Class)_타입(Type)

클래스_정렬 sort, Comparator, Collections.sort()

쎈코 2023. 3. 1. 01:12

1. 배열 정렬

1. 순수배열

int[] nums = { 1, 5, 3, 4, 2 };
System.out.println(Arrays.toString(nums));            //[1, 5, 3, 4, 2]

Arrays.sort(nums);                                                  //정렬
System.out.println(Arrays.toString(nums));             //[1, 2, 3, 4, 5]


2. ArrayList
ArrayList nums2 = new ArrayList();

nums2.add(1);
nums2.add(5);
nums2.add(4);
nums2.add(3);
nums2.add(2);

System.out.println(nums2);                                    //[1, 5, 4, 3, 2]
Collections.sort(nums2);                                        //정렬
System.out.println(nums2);                                    //[1, 2, 3, 4, 5]

더보기

TODO 왜 Collections.sort()를 쓴 걸까?

ArrayList 클래스는 List 인터페이스를 구현한 클래스 중 하나로, 요소들을 배열로 저장함.

Collections.sort() 메소드는 List 인터페이스의 구현을 받는 객체를 정렬하는 메소드이며,

ArrayList도 List 인터페이스를 구현하므로 Collections.sort() 메소드를 사용할 수 있음.

 

반면에 Arrays.sort() 메소드는 배열을 정렬하는 메소드임. 위의 코드에서 nums2는 ArrayList로 선언되었으므로,

배열이 아닌 리스트 형태로 요소들이 저장되어 있음. 그러므로 Arrays.sort() 메소드를 사용할 수 없음.

 

따라서 nums2를 정렬하기 위해서는 Collections.sort() 메소드를 사용해야 함. 

Collections.sort(nums2)를 호출하여 정렬하면 [1, 2, 3, 4, 5]가 출력



Student[] list = new Student[5];
list[0] = new Student("가가가", 100, 90, 80);
list[1] = new Student("나나나", 99, 98, 88);
list[2] = new Student("다다다", 87, 89, 79);
list[3] = new Student("라라라", 65, 67, 87);
list[4] = new Student("마마마", 76, 79, 68);

// Arrays.sort(list);    //에러

//java.lang.ClassCastException: class com.test.obj.type.Student cannot be cast to class java.lang.Comparable 
-> 뭘 기준으로 오름차순/내림차순 정렬할지? 가나다 순으로 정렬할지, 점수 순으로 정렬할지 등 기준이 없음

 

for(int i=0; i<list.length-1; i++) {
     for(int j=0; j<list.length-1-i; j++) {
          if((list[j].getKor() + list[j].getEng() + list[j].getMath()) < (list[j+1].getKor() + list[j+1].getEng() + list[j+1].getMath())) {

              Student temp = list[j];
              list[j] = list[j+1];
              list[j+1] = temp;
          }
     }
}
System.out.println(Arrays.toString(list));

 

2. comparator

Integer[] nums = { 1, 5, 4, 2, 3 };
Arrays.sort(nums);                                              //기존에는 Arrays.sort만 하면 정렬 됨
System.out.println(Arrays.toString(nums));        //[1, 2, 3, 4, 5]

MyComparator my = new MyComparator();      //클래스도 만들고 메소드도 만들고 해야 정렬 가능 > 복잡, 불편

Arrays.sort(nums, my);
System.out.println(Arrays.toString(nums));


3. comparator를 더 쉽게(익명 객체(Comparator) 생성)

Integer[] nums = { 1, 5, 4, 2, 3 };

//정렬하고 싶은데 아래에 또 클래스를 만들기 귀찮으니까 여기서 바로 만듦

//Comparator는 인터페이스임
//익명 클래스로부터 만들어진 익명 객체임
Comparator<Integer> my = new Comparator<Integer>() {                                       
// 눈에 안보이지만 클래스를 하나 만든거고 그 클래스는 Comparator 인터페이스를 상속받는 것임

// Comparator 클래스를 상속받는 MyComparator의 몸(구현부)을 가져옴
// => MyComparator의 객체와 똑같은 애임
     public int compare(Integer o1, Integer o2) {
          //내림차순
          return o2 - o1;
          } 
     };
//내림차순으로 정렬
Arrays.sort(nums, my);
System.out.println(Arrays.toString(nums));


4. 2, 3번을 더 쉽게

Integer[] nums = { 1, 5, 4, 2, 3 };

Arrays.sort(nums, new Comparator<Integer>() {
     public int compare(Integer o1, Integer o2) {
     return o2 - o1;
     }
}); //익숙해질때까지 공부해야함. 굉장히 많이 쓰기 때문

 

 

5. 문자열 배열(오름차순, 내림차순, 사용자 정의대로)

String[] names = {"홍길동", "아무개", "하하하", "가가가", "나나나", "김민", "남궁재민" };

1. 가나다순 > 오름차순만 가능
Arrays.sort(names);
System.out.println(Arrays.toString(names));

 

 

2. 오름차순, 내림차순 가능
//Comparator로 구현
//Comparator<비교하는 대상> 

//내림차순 정렬
Arrays.sort(names, new Comparator<String>() {          //names 배열을 익명클래스인 new Comparator() 클래스대로 구현
     public int compare(String o1, String o2) {
          return o2.compareTo(o1);                                   //o1과 o2를 큰지 작은지 비교해서 양수, 음수 또는 0으로 반환
          //문자나 날짜 비교는 compareTo 사용
     }
});
System.out.println(Arrays.toString(names));


3. 사용자 정의: 글자수 순으로(글자수 적은거 -> 많은거)
Arrays.sort(names, new Comparator<String>() {
     public int compare(String o1, String o2) {
          return o1.length() - o2.length();                       //글자수로 비교하는거니까 length로 구
     }
});
System.out.println(Arrays.toString(names));


6. Comparator를 구현해서 지정 비교

Student[] list = new Student[5];

list[0] = new Student("가가가", 100, 90, 80);
list[1] = new Student("나나나", 99, 98, 88);
list[2] = new Student("다다다", 87, 89, 79);
list[3] = new Student("라라라", 65, 67, 87);
list[4] = new Student("마마마", 76, 79, 68);


Arrays.sort(list, new Comparator<Student>() {
     public int compare(Student o1, Student o2) {

     //총점을 내림차순 정렬(두번째 인자값이 앞으로 와야함)
     return (o2.getKor() + o2.getEng() + o2.getMath()) - (o1.getKor() + o1.getEng() + o1.getMath());
     }
});
System.out.println(Arrays.toString(list));

 

7. Collections.sort() 사용

ArrayList<Integer> nums = new ArrayList<Integer>();             //ArrayList<Integer> 객체 생성

nums.add(5);
nums.add(4);
nums.add(2);
nums.add(1);
nums.add(3);

Collections.sort(nums, new Comparator<Integer>() {                 //객체를 정렬할때는 Collections.sort()를 사용
     public int compare(Integer o1, Integer o2) {                           //익명 객체 생성 후 구현부 작성
          return o1 - o2;            //오름차순
     }
});
System.out.println(nums);

                ↓ ↓ ↓ ↓ ↓

//굳이 Collections.sort 할 필요 없이 바로 배열.sort로 구현하는게 더 쉬움
nums.sort(new Comparator<Integer>() {
     public int compare(Integer o1, Integer o2) {
          return 0;
     }
});


class Student{

private String name;
private int kor;
private int eng;
private int math;

public Student(String name, int kor, int eng, int math) {
     this.name = name;
     this.kor = kor;
     this.eng = eng;
     this.math = math;
}

public String getName() {
     return name;
}

public void setName(String name) {
     this.name = name;
}

public int getKor() {
     return kor;
}

public void setKor(int kor) {
     this.kor = kor;
}

public int getEng() {
     return eng;
}

public void setEng(int eng) {
     this.eng = eng;
}

public int getMath() {
     return math;
}

public void setMath(int math) {
     this.math = math;
}

public String toString() {
     return "Student [name=" + name + ", kor=" + kor + ", eng=" + eng + ", math=" + math + "]";
}


} //Student class


class MyComparator implements Comparator<Integer>{

정렬할 때 비교를 담당하는 메소드
o1 vs o2
- 오름차순
    - o1 > o2 o1이 크면  => 양수 반환
   - o1 < o2 o1이 작으면 => 음수 반환
    - o1 = o2 둘이 같으면 => 0 반환

- 내림차순
   - o1 > o2 => 음수 반환
   - o1 < o2 => 양수 반환
    - o1 = o2 => 0 반환

     public int compare(Integer o1, Integer o2) {            //list[j], list[j+1]
     //오름차순 -> 굳이 이렇게 안만들음
          if(o1 > o2) {
              return 1;  //숫자가 어떤건진 중요하지 않음. 양수만 돌려주면 됨
          } else if (o1 < o2) {
                return -1; 
          } else {
               return 0;
           }

         //훨씬 간단한 방법
         return o1 - o2;
     }
}