익명 클래스 (Anonymous Class)
람다식을 이해하기 위해선 익명함수를 이해해야한다.
익명클래스란 내부클래스의 일종으로 말그대로 이름이 없는 클래스를 말한다.
이름이 없다는 것은 부를필요가 없다는 것으로 그 클래스 내부의 구현이 다변하게 변경될 때 종류별로 클래스를 정의하긴 힘들기 때문에 사용한다.
익명클래스를 사용하는 예시
익명클래스를 사용하는 가장 대표적인 예시는 sort()메소드를 사용할 때다.
sort()메소드는 인자로 Comparator 인터페이스의 구현체를 받는데 이 Comparator 구현체를 통해 정렬하는 기준을 정의한다.
Compartor 구현체예시
import java.util.Comparator;
class Student {
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
// 게터 세터
}
class NameComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
}
- Student 클래스의 이름을 기준으로 오름차순 정렬을 해주는 기준을 Compartor 구현체를 통해 정의해 줬다.
구현체를 통해 sort()메소드 사용
Student[] students = new Student[3];
students[0] = new Student("김범석", 19, 100);
students[1] = new Student("박해민", 32, 80);
students[2] = new Student("김현수", 38, 60);
Arrays.sort(students, new Comparator<Student>() { // 무명 클래스
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});
하지만, 만약 어쩔땐 내림차순으로 정렬하고 싶고, 또 어쩔 땐 나이로 정렬하고 싶어질 수도 있다. 그럴 때마다 Compartor 구현체를 정의해줘야하는데 이러면 너무 비효율적이다.
그래서 사용하는 것이 익명클래스이다.
위의 코드를 익명클래스로 작성하면 다음과 같다.
Student[] students = new Student[3];
students[0] = new Student("김범석", 19, 100);
students[1] = new Student("박해민", 32, 80);
students[2] = new Student("김현수", 38, 60);
Arrays.sort(students, new Comparator<Student>() { // 익명 클래스
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});
- 내가 정렬하고 싶은 그 순간에만 Comparator를 구현하는 것이다.
람다식
람다식은 익명클래스를 더 간편하게 쓰고싶을 때 사용한다.
람다는 익명클래스가 메소드를 하나만 재정의할 때 사용한다.
Student[] students = new Student[3];
students[0] = new Student("김범석", 19, 100);
students[1] = new Student("박해민", 32, 80);
students[2] = new Student("김현수", 38, 60);
Arrays.sort(students, new Comparator<Student>() { // 익명 클래스
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});
- 익명클래스가 차지하는 부분이 꽤 많은 것을 알 수 있다.
람다를 사용하는 방식은 다음과 같다.
(매개변수) -> { 메소드 실행문 }
위의 코드를 람다식으로 작성한다면 다음과 같다.
Student[] students = new Student[3];
students[0] = new Student("김범석", 19, 100);
students[1] = new Student("박해민", 32, 80);
students[2] = new Student("김현수", 38, 60);
Arrays.sort(students, (o1, o2) -> {
return o2.getName().compareTo(o1.getName());
});
하지만 개발자들의 욕심은 끝이 없다...
더 간편하게 쓸 순 없을까?
가능하다.
우선 매개변수가 하나면 소괄호를 생략할 수 있다.
(o) -> { }
-->
o -> { }
또한 메소드 실행문이 return 한 문장이면 중괄호와 return 키워드도 생략이 가능하다
o -> { return -1 }
-->
o -> -1
람다식(익명클래스)의 특징
- 람다도 하나의 메소드라서 내부에 지역변수를 만들어 쓸 수 있다.
public class Test04 {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("김", 19, 100);
students[1] = new Student("이", 32, 80);
students[2] = new Student("박", 38, 60);
Arrays.sort(students, (o1, o2) -> {
String inner = ""; // 가능
return o2.getName().compareTo(o1.getName());
});
}
}
- 하지만 람다식 밖에 있는 지역변수를 건드리면 안된다. 그런데 또 클래스의 필드는 가능하다.
public class Test04 {
public static String field;
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("김", 19, 100);
students[1] = new Student("이", 32, 80);
students[2] = new Student("박", 38, 60);
String outLocal;
Arrays.sort(students, (o1, o2) -> {
outLocal = "수정"; // 불가능
field = "수정"; // 가능
return o2.getName().compareTo(o1.getName());
});
}
}
'Java' 카테고리의 다른 글
[Java] 해시기반 컬렉션의 동등성 비교(hashCode() 메서드의 필요성) (0) | 2024.07.25 |
---|---|
[Java] Stream API (0) | 2024.07.25 |
[Java] HashMap - value값을 기준으로 정렬 (0) | 2024.07.23 |
[Java] HashSet - 객체의 속성으로 중복 체크 (0) | 2024.06.21 |
[Java] 배열 정렬하기 (0) | 2024.06.16 |