람다식이란
길고 복잡하게 쓰여지는 메소드나 함수를 간단하게 정리하여 짧게 쓸 수 있는 익명 함수(메소드)이다.
람다식은 인터페이의 구현으로만 가용할 수 있다.
람다식의 장점
- 코드의 간결성 : 람다를 사용하면 불필요한 반복문의 삭제가 가능하며 복잡한 식을 단순하게 표현할 수 있다.
- 지연연산 수행 : 람다는 지연연상을 수행 함으로써 불필요한 연산을 최소화 할 수 있다.
- 병렬처리 가능 : 멀티쓰레드를 활용하여 병렬처리를 사용 할 수 있다.
람다식의 단점
- 람다식의 호출이 까다로울 수 있다.
- 불필요하게 너무 사용하게 되면 오히려 가독성을 떨어질 수 있다.
람다식 의 일반적인 구문
(parameter ,,,) -> { body }
람다식 활용 실습
package lambda;
// Lambda Expression : 이름이 없는 익명 함수(메소드)
// 람다 표현식은 함수형 인터페이스의 구현으로만 가용할 수 있다.
// 하나의 추상 메소드를 가져야 하며, 람다 표현식은 해당 메소드의 구현으로 동작한다.
@FunctionalInterface
interface HelloInter{ // Lambda Expression을 사용할 인터페이스
// 추상 메소드는 반드시 하나만 있어야함. 이것을 함수형 인터페이스라고 부른다
int calcData(int a, int b);
// int calcData2(int a, int b);
}
public class MyLambda1 implements HelloInter{
@Override
public int calcData(int a, int b) {
// 인터페이스 추상 메소드 오버라이딩 : 전통적 방법
return a + b;
}
// @Override
// public int calcData2(int a, int b) {
// // TODO Auto-generated method stub
// return 0;
// }
public static void main(String[] args) {
MyLambda1 my = new MyLambda1();
System.out.println(my.calcData(3, 4)); // 전통적(legacy) 방법
System.out.println();
// 인터페이스 변수 = 람다식
// 람다 표현식의 일반적인 구문 : (parameter ,,,) -> { body }
HelloInter inter = (x, y) -> x + y;
System.out.println(inter.calcData(4, 5));
HelloInter inter2 = (x, y) -> x * y;
System.out.println(inter2.calcData(4, 5));
}
}
package lambda;
interface MyInter {
void aaa();
}
interface MyInterArg {
void bbb(int a, int b);
}
interface MyInterArgReturn {
int ccc(int a, int b);
}
public class MyLambda2 {
public static void main(String[] args) {
// 1. 인자가 없는 추상 메소드 처리 : 전통적
MyInter inter = new MyInter() {
@Override
public void aaa() {
System.out.println("익명 클래스의 메소드 오버라이딩");
}
};
inter.aaa();
// 람다식으로 표현 1
MyInter inter2 = () -> {
System.out.println("익명 클래스의 aaa 메소드 오버라이딩");
};
inter2.aaa();
MyInter inter3 = () -> {
int imsi = 10;
System.out.println("람다식으로");
System.out.println("복수의 명령 처리");
System.out.println("imsi : " + imsi);
};
inter3.aaa();
// 2. 인자가 있는 추상 메소드 처리 : 전통적
MyInterArg interArg = new MyInterArg() {
@Override
public void bbb(int a, int b) {
System.out.println("두 수의 합은 : " + (a + b));
}
};
interArg.bbb(3, 4);
// 람다식으로 표현 2 : arg가 1개일 경우 (a) -> 또는 a -> 로 적음
MyInterArg interArg2 = (a, b) -> System.out.println("람다로 구한 두 수의 합은 : " + (a + b));
interArg2.bbb(5, 6);
System.out.println("---------");
// 3. 인자가 있고 반환값도 있는 추상 메소드 처리
MyInterArgReturn argReturn = new MyInterArgReturn() {
@Override
public int ccc(int a, int b) {
System.out.println("ccc 처리");
return a + b;
}
};
int result = argReturn.ccc(5, 6);
System.out.println("두 수를 더한 결과 : " + result);
MyInterArgReturn argReturn2 = (a, b) -> a + b;
// 람다식으로 표현 3
MyInterArgReturn argReturn3 = (a, b) -> {
System.out.println("람다로 ccc 처리");
return a + b;
};
argReturn3.ccc(7, 8);
int result2 = argReturn.ccc(5, 6);
System.out.println("두 수 더함 : " + result2);
}
}
package lambda;
import java.io.File;
import java.util.Arrays;
import java.util.List;
public class Mylambda3 {
public Mylambda3() {
// TODO Auto-generated constructor stub
test1(); // List collection을 이용해서 람다 표현식
System.out.println("------");
test2(); // Thread를 사용
System.out.println("------");
test3(); // FileFilter를 사용한 파일 필터링
}
private void test1() {
List<String> list = Arrays.asList("Apple", "Banana", "Cherry");
// 전통척인 방법으로 출력
for(String i:list) {
System.out.println(i);
}
System.out.println();
// 위 for문을 람다식 사용
// forEach는닌 Consumer 함수형 인터페이스의 인스턴스를 받아, 각 요소애 대한 작업을 정의한다.
// Consumer : 반환 값이 없으며, 1개의 매개변수를 받아들이고 반환값이 없는 accept()를 정의
list.forEach(i -> System.out.println(i));
}
class ThreadTest {
public void sendData(String friend) {
System.out.println(friend + "에게 문자 전송");
}
public ThreadTest() {
// TODO Auto-generated constructor stub
}
void m1() { // 전통적 방법
new Thread(new Runnable() {
@Override
public void run() {
sendData("Richard");
}
}).start();
}
void m2() { // 람다 표현식
Runnable runnable = () -> sendData("Brian");
runnable.run();
}
void m3() {
Thread thread = new Thread(() -> sendData("Linda"));
thread.start();
}
void m4() {
new Thread(() -> sendData("Betty")).start();
}
}
private void test2() {
ThreadTest threadTest = new ThreadTest();
threadTest.m1();
threadTest.m2();
threadTest.m3();
threadTest.m4();
}
private void test3() {
// 특정 디렉토리(폴더)에 있는 파일 목록 걸러보기
File direc = new File("c:/work");
// FileFilter 함수형 인터페이스로 람다식 처리. 확장자 txt만 필터링
File[] files = direc.listFiles((File file) -> file.isFile() && file.getName().endsWith(".txt"));
if(files != null) {
for(File f:files) {
System.out.println(f.getName());
}
}
}
public static void main(String[] args) {
new Mylambda3();
}
}
package lambda;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MyLambda4 {
public static void main(String[] args) {
JFrame frame = new JFrame("람다 연습");
JButton button1 = new JButton("click1"); // 이벤트 처리
JButton button2 = new JButton("click2"); // 람다로 이벤트 처리
JButton button3 = new JButton("click3"); // 컬렉션 처리
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 전통적 방법
System.out.println("전통적 방법으로 이벤트 처리");
}
});
button2.addActionListener(e -> System.out.println("람다 사용 이벤트 처리"));
button3.addActionListener(e -> callMethod());
frame.add("North", button1);
frame.add("Center", button2);
frame.add("South", button3);
frame.setBounds(200, 200, 400, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
static void callMethod() {
// System.out.println("a");
ArrayList<jikwon> jikwons = new ArrayList<MyLambda4.jikwon>();
jikwons.add(new jikwon(3, "홍길동"));
jikwons.add(new jikwon(1, "고길동"));
jikwons.add(new jikwon(2, "나길동"));
System.out.println("정렬 전 : ");
// for(jikwon j:jikwons) {
// System.out.println(j.bunho);
// }
// accept(jikwon j){
// System.out.println(j.bunho + " " + j.irum);
// }
jikwons.forEach(j -> System.out.println(j.bunho + " " + j.irum));
System.out.println("Collection.sort 사용");
// 특정 메소드의 매개변수로 람다식 사용
Collections.sort(jikwons, new Comparator<jikwon>() {
public int compare(jikwon o1, jikwon o2) {
return o1.bunho - o2.bunho;
}
});
System.out.println("정렬 후 :");
jikwons.forEach(jik -> System.out.println(jik.bunho + " " + jik.irum));
System.out.println("정렬 후 2 (람다 사용) : ");
Collections.sort(jikwons, (o1, o2) -> o1.bunho - o2.bunho);
jikwons.forEach(jik -> System.out.println(jik.bunho + ". " + jik.irum));
}
static class jikwon{
int bunho;
String irum;
public jikwon(int bunho, String irum) {
this.bunho = bunho;
this.irum = irum;
}
}
}
'Java' 카테고리의 다른 글
html과 jsp 맛보기 (10) | 2024.07.24 |
---|---|
웹 서버 만들기 기초 (1) | 2024.07.24 |
네트워크, URL, 서버 (0) | 2024.07.24 |
Stream, 람다식 DB 연동 활용 (1) | 2024.07.24 |
배열(Array) (0) | 2024.04.11 |