Java

람다식 활용

걷는 청년 2024. 7. 24. 11:53

람다식이란

길고 복잡하게 쓰여지는 메소드나 함수를 간단하게 정리하여 짧게 쓸 수 있는 익명 함수(메소드)이다.

람다식은 인터페이의 구현으로만 가용할 수 있다. 

 

람다식의 장점

 

- 코드의 간결성 : 람다를 사용하면 불필요한 반복문의 삭제가 가능하며 복잡한 식을 단순하게 표현할 수 있다.
- 지연연산 수행 : 람다는 지연연상을 수행 함으로써 불필요한 연산을 최소화 할 수 있다.
- 병렬처리 가능 : 멀티쓰레드를 활용하여 병렬처리를 사용 할 수 있다.

 

 

람다식의 단점

 

- 람다식의 호출이 까다로울 수 있다.
- 불필요하게 너무 사용하게 되면 오히려 가독성을 떨어질 수 있다.

 

람다식 의 일반적인 구문

 (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