Java Lambda식 + Comparable 및 Comparator 인터페이스
🧑‍💻 𝗣𝗿𝗼𝗴𝗿𝗮𝗺𝗺𝗶𝗻𝗴/Java

Java Lambda식 + Comparable 및 Comparator 인터페이스

 

 

 

 Lambda 

개요

람다를 알기 이전에 우리는 Funtional Interface 에 대해서 짚고 넘어갈 필요가 있습니다.

Funtional Interface 란 재정의될 추상 메서드가 딱 하나뿐인 인터페이스를 이릅니다.

이는 Single Abstract Method (SAM) 라기도 하며, 아주 구체적이고 전문적인 기능을 하는 메서드를 만들고 싶을 때 사용합니다.

https://docs.oracle.com/javase/8/docs/api/

 

Java Platform SE 8

 

docs.oracle.com

우리가 알아볼 Comparable 인터페이스가 그런 형식입니다.

이게 근데 람다와 무슨 관련이 있을까요?

바로 sorting 을 하기 위해 Comparable<T> 를 사용할 때, Comparator<T> 인터페이스를 매개변수로 받는데

이를 람다식으로 표현하여 편리하게 넘길 수 있기 때문입니다.

 

 

람다식

만약 javascript 나 python 을 이용해보신 분이라면 익명함수 (Anonymous Funtions) 가 무엇인지 알고 계실 것입니다.

java 에서도 마찬가지로 람다식이 이용이 됩니다. 람다식은 익명함수의 통칭입니다.

람다식을 이용하면 굳이 부차적인 코딩을 하지 않아도 돼서 개발에 용이성을 높여주죠.

public int add(int a, int b) {
	return a + b;
}

예를 들어 위와 같은 함수식이 있다고 가정합시다. 이를 익명함수로 바꾼다면 아래와 같이 변경할 수 있습니다.

int n = (a, b) -> a + b;

무척 간단하죠? 

int n = (a, b) -> { return a + b; }

java 에서는 {} 를 많이 사용하니 위와 같이 나타낼 수도 있을 것입니다.

 

 

예제

// Functional Interface
package first.m07.subject01.lambda;


public interface MyNote {
	String write(int no, String content);
}
// MyNote 를 implements 하는 MyNoteImpl 클래스
package first.m07.subject01.lambda;


public class MyNoteImpl implements MyNote {

	@Override
	public String write(int no, String content) {
		return String.format("%d %s", no, content);
	}

}
package first.m07.subject01.lambda;


public class Test {
	public static void main(String[] args) {
		{
			MyNote note = new MyNoteImpl();
			String str = note.write(1, "노트1");
			System.out.println(str);
		}

		{
			MyNote note = new MyNoteImpl() {
				@Override
				public String write(int no, String content) {
					return String.format("%d %s 입니다.", no, content);
				};
			};
			String str = note.write(2, "노트2");
			System.out.println(str);
		}

		{
			MyNote note = (no, content) -> {
				return String.format("%d %s 입니다요.", no, content);
			};
			String str = note.write(3, "노트3");
			System.out.println(str);
		}

	}
}

저런식으로 람다 클래스를 만들고, 람다식 함수로 확장을 할 수 있습니다.

 

 

 

 Comparable<T> 와 Comparator<T> 

위 인터페이스를 이용해서 람다식이 얼마나 간편한지 한번 알아보겠습니다.

객체를 정렬할 때, 비교 기준을 제시하지 않는다면 객체를 정렬할 수 없을 것 입니다.

이러한 비교 기준을 자바에서는 Comparable 와 Comparator 가 제시합니다.

 

보시면 아시겠지만 Comparable 와 Comparator 모두 Interface 입니다.

여기서 우리가 구현해서 사용해야 할 것은 딱 두가지의 메서드 입니다.

1. Comparable<T> 의 compareTo()
2. Comparator<T> 의 compare()

Comparator 는 다른 메서드가 많아 다른 것도 재정의를 해야하지않나? 라고 생각이 들 수 있지만

compare() 을 제외하고는 다 default 나 static 으로 정의되어 구현부가 작성되어 있기 때문에 재정의 하지 않아도 됩니다.

 

 

비교되는 값

그리고 또 api document 를 참조하면 알 수 있는 점이 compare(T o1, T o2) 로 매개변수가 2개 이고,

compareTo(T o) 는 매개변수가 하나 입니다.

즉, compareTo() 해당 메서드가 사용되는 클래스 객체와 비교가 되는 것입니다.

예를 들어 o1.compareTo(o2); 라고 한다면 o1 와 o2 가 비교되는 것이지요.

compare() 은 어떻게 될까요? o3.compare(o1, o2); 라면 o1 와 o2 가 비교됩니다.

 

 

반환 값

정수를 반환한다. -1 (음수), 0, 1 (양수)

둘 다 int 값을 반환하는 것을 확인할 수 있습니다.

따라서 비교되는 기준을 세울 때 정수로 반환되도록 세워야 합니다.

 

 

Arrays.sort(T[] a, Comparator<? super T> c)

여기까지 왔는데도 감이 잘 안잡힙니다. 그래서 Comparable 과 Comparator 가 뭐 어쩌라는 것일까요.

바로 그 해답은 Arrays.sort() 에 있습니다. Arrays api 를 보면 sort() 메서드가 있는 것을 확인할 수 있습니다.

보면 첫번째를 제너릭으로 받고, 두번째는 Comparator<T> 로 받습니다.

 

Arrays.sort() 를 이용해서 객체 배열을 정렬할 수 있는데

여기서 Comparator<T> 에 람다식을 사용하면 쉽게 원하는 비교 기준으로 정렬을 할 수 있게 됩니다.

Arrays.sort(strs, (o1, o2) -> {o1.length() - o2.length()});

예를 들어 String[] 타입의 strs 배열을 문자열의 길이를 기준으로 정렬을 하고 싶다고 합시다.

그러면 저런식으로 뒤에 Comparator<T> 를 받는 매개변수 부분에 람다식을 사용하여

비교기준을 길이로 설정을 하면 되는 것입니다.

 

return 이 정수이니 만약 음수를 리턴하면 o1.length() - o2.length() < 0 이 되어 o1 보다 o2 의 길이가 더 길다. 이런식으로 정렬을 할 수가 있게 되겠죠. 이렇게 객체 배열을 람다식을 이용하여 정렬할 수 있게 됩니다.

 

 

 

 

 

# java lambda # java anonymous functions # 자바 comparable # 자바 comparator

# java comparable comparator


 

728x90