부트캠프(Java)

자바 / 스프링 부트캠프 10일차 ( 람다식 , 내부클래스, 예외처리)

동곤일상 2025. 2. 13. 17:39
반응형

 

어제에 이어서 람다식을 하네요!!

 

1) 람다식

1-1) 추상메서드가 매개변수 , 리턴타입이 없는경우

1-2) 추상메서드의 매개변수가있고 리턴타입은 void인경우

 

1-3)  추상메서드의 매개변수,리턴값 모두존재 

 

2) 내부클래스

 

   2-1) 예시

 

   2-2) 내부클래스에서 this 와 super 사용하기

 

   2-3) 람다객체에서 this

 

3) 예외처리

 

4) 인터페이스 , 내부클래스 예제


@@ 1) 람다식 @@

* 함수적 인터페이스(FunctionalInterface) : 

인터페이스의 추상메서드가 한개인 인터페이스


 * 함수적 인터페이스만 람다방식으로사용가능
 


 


 1-1) 추상메서드가 매개변수 , 리턴타입이 없는경우


 * fi = () ->{...};
 * 내부의 문장이 하나인경우는 {} 생략가능
 * fi = ()->...

package chap8;

@FunctionalInterface    //함수적 인터페이스로 설정하므로 추상메서드가 1개여야함을 표시
interface LambdaInterface1{
	void method(); //매개변수 없고 리턴타입도 없는경우
//	void method2();
}
//-------------------------------------------------------------------
public class LambdaEx1 {
	
	public static void main(String[] args) {
		LambdaInterface1 f1;
		
//-------------------------------------------------------------------
		// 0. 익명클래스 이용
		
		f1=new LambdaInterface1() {
			
			@Override
			public void method() {
				System.out.println("기존의 내부객체로 생성함");
			}
		};f1.method();
	
//-------------------------------------------------------------------	-------	
		//1.람다식으로 변경
		
		f1 = ()->{
			String str = "람다방식 1 ";
			System.out.println(str);
		};f1.method();
		
//-------------------------------------------------------------------	-------			
		
		//2.람다방식 : 내부 문장이 한개인경우 {} 생략가능
		
		f1 = ()-> System.out.println("람다방식 2 ");
		f1.method();
		
//-------------------------------------------------------------------	-------	
		//3. LambdaInterface1 인터페이스를 매개변수로받는 static메서드로 람다방식이용
		
		execute(()->System.out.println("excute메서드에서 호출함"));
		
		//execute 함수 이용해 1~100까지의 합 출력
		execute(()->{
			System.out.print("1에서100까지의 합 : ");
			int num =100;
			int sum=0;
			for (int i = 1; i <= num; i++) {
				sum+=i;
			}
			System.out.println(sum);
		});
		
		//excute 함수를 이용해 1~100까지의 짝수합 출력해보기
		execute(()->{
			System.out.print("1에서100까지의 짝수 합 : ");
			int num =100;
			int sum=0;
			for (int i = 1; i <= num; i++) {
				if(i%2==0) {
					sum+=i;
				}
			}
			System.out.println(sum);
			
			
		});
		
	}
	
	public static void execute(LambdaInterface1 l) {
		System.out.println("excute 시작");
		l.method();
		System.out.println("excute 종료");
	}

}

기존의 내부객체로 생성함

람다방식 1

람다방식 2

excute 시작

excute메서드에서 호출함

excute 종료

excute 시작

1에서100까지의 합 : 5050

excute 종료

excute 시작

1에서100까지의 짝수 합 : 2550

excute 종료

 

 


1-2) 추상메서드의 매개변수가있고 리턴타입은 void인경우

 

* (매개변수)->{...};

* 매개변수가 1개인 경우 () 생략가능

* 실행구문이 1개인경우 {} 생략가능

 

package chap8;

interface Lambda2{
	void method(int a);
}

public class LambdaEx2 {
	public static void main(String[] args) {

		Lambda2 l;
		
		l=x->{
			System.out.println(x+" * 3 : "+x*3);
			};
		l.method(4);
		
		calc(l, 5);
	}
	
	private static void calc(Lambda2 f ,int num) {
		f.method(num);
	}
}

4 * 3 : 12

5 * 3 : 15

 


예제

package chap8;
/*
 * 
 * interface Lambda2{ 
	void method(int a);}
 */
public class Exam2 {
	
	private static  void calc2(Lambda2 f , int num) {
		f.method(num);
	}
	
	public static void main(String[] args) {
		Lambda2 f;
//------------------------1부터x까지의 합 만들어보기 ----------------------		
		f=(x)->{
			int sum=0;
			for (int i = 0; i <= x; i++) {
				sum+= i;
			}
			System.out.println("1부터"+x+"까지의 합 : "+sum);
		};// Lamda2의 메서드를 이렇게 바꾸는거임
		
		calc2(f,10);
		calc2(f, 20);
//----------------------------메서드 동작변경-----------------------------------------------		
		f=(x)->{
			System.out.println(x+"+ 10 = "+(x+10));
		};
		//이  이후에 쓰는 Lambda2의 method
		calc2(f, 10); 
//----------------------------x!값 출력해보자-----------------------------------------------
		f=(x)->{
			int fact=1;
			for(int i = x ; i>=1; i--) {
				fact *= i;
			}
			System.out.println(x+"!  : "+fact);
		};
		calc2(f, 4);
		
	}
}

1부터10까지의 합 : 55

1부터20까지의 합 : 210

10+ 10 = 20

4! : 24


 

1-3)  추상메서드의 매개변수,리턴값 모두존재 

 


 * 매개변수와 리턴값 모두 있는 경우
 * 매개변수의 갯수가 한개인경우 () 생략가능
 * {} 내부에 문장이 한개인경우 { }, return 생략가능

 

package chap8;
interface LamdaInterface3{
	int method(int x, int y);
}
public class LambdaEx3 {
	public static void main(String[] args) {
		LamdaInterface3 f = (x,y)->{
			return x+y;
			};
		
		System.out.println("두수의 합 : "+f.method(2, 5));
		
		f=(x,y) -> x + y;
		System.out.println("두수의합 : "+f.method(2, 3));
		
		f=(x,y) -> x * y;
		System.out.println("두수의 곱 : "+f.method(10, 2));
		
		f=(x,y) -> x / y;
		System.out.println("두수의 몫 : "+f.method(240, 2));

		f=(x,y) -> x & y;
		System.out.println("두수의 나머지 : "+f.method(10, 4));
		
		f=(x,y) -> {
			if(x>y) {return x;}
			else {return y;}
		};
		System.out.println("두수 중 큰 수: "+f.method(10, 4));
		
		f=(x,y)->(x<y)?x:y;
		System.out.println("두수 중 작은 수: "+f.method(10, 4));
	}
}

@@ 2) 내부클래스 @@

 

 

 내부클래스 : 클래스내부에존재하는 클래스

 

@ 인스턴스내부클래스 : 객체화가 되기 위해서는 외부클래스의 객체화 필요 ->

         외부클래스참조변수.new 내부클래스명();

          new 외부클래스().new 내부클래스();

 

@ static 내부클래스 : 객체화가 되기 위해서는 -> new 외부클래스명.내부클래스명();

 

*@지역 내부클래스 : 메서드 내부에서 선언된 내부클래스

                               선언된 메서드 내에서만 사용할 수 있다.

 

@ 내부클래스 특징

* 1.참조자료형으로 사용됨 . 외부클래스명.내부클래스명

* 2. 객체화가능

  3.. 멤버소유가능 , 생성자 구현가능

  4.외부클래스의멤버임.

 1).외부클래스의 private멤버에 접근가능

 2.)인스턴스내부클래스 : 인스턴스멤버

  3.)static내부클래스 : 클래스멤버

 


 

2-1)  코드 예시

package chap9;

import chap9.Outer1.InstanceInner;
import chap9.Outer1.StaticInner;

class Outer1{
	int iv=40;
	static int cv=30;
	
	class InstanceInner{//내부클래스
		int iv=100;
		static int cv = 10;
		final static int MAX = 200;
		int outerIv= Outer1.this.iv;//바깥클래스 멤버 접근법
	}
	
	static class StaticInner{//static 내부클래스
		int iv=300;
		static int cv = 400;
		final static int MAX = 500;
	}
	
	void method() {//Outer1의 멤버
		
		class LocalInner{//Local내부클래스
			int iv=600;
			static int cv = 700;
			final static int MAX = 800;

		}
		LocalInner lc = new LocalInner();//객체화
		
		System.out.println("====="+lc.getClass()+"====");
		System.out.println("lc.iv : "+lc.iv);
		System.out.println("lc.cv : "+LocalInner.cv);
		System.out.println("LocalInner.MAX : "+LocalInner.MAX);
		System.out.println("this.iv : "+this.iv);//외부클래스(자신의클래스) 멤버 접근가능
	}
	
	void method2() {
//		LocalInner lc = new LocalInner();
		//오류발생 , method()내부에서만 호출가능한 내부클래스
	}
}
public class InnerEx1 {
	public static void main(String[] args) {
		Outer1 outer1 = new Outer1();
		
		InstanceInner i = outer1.new InstanceInner();//내부클래스 생성법1
		InstanceInner i2 = new Outer1().new InstanceInner();//생성법2
		System.out.println("======= 내부클래스 =======");
		System.out.println("i.iv : "+i.iv);
		System.out.println("i.cv : "+InstanceInner.cv);
		System.out.println("outerIv : "+i.outerIv);
		System.out.println("InstanceInner.MAX : "+InstanceInner.MAX);
		
		StaticInner s = new Outer1.StaticInner();//static클래스 생성법
		System.out.println("======static 내부 클래스=======");
		System.out.println("s.iv : "+s.iv);
		System.out.println("s.cv : "+StaticInner.cv);
		System.out.println("StaticInner.MAX : "+StaticInner.MAX);
		StaticInner s2 = new StaticInner();//그냥 클래스만으로도 생성가능
		
		
		outer1.method();//지역클래스는 메서드안에서만사용됨
	}
}

======= 내부클래스 =======

i.iv : 100

i.cv : 10

outerIv : 40

InstanceInner.MAX : 200

======static 내부 클래스=======

s.iv : 300

s.cv : 400

StaticInner.MAX : 500

=====class chap9.Outer1$1LocalInner====

lc.iv : 600

lc.cv : 700

LocalInner.MAX : 800

this.iv : 40

 

 


예시

 

package chap9;

import chap9.Outer2.InstanceInner;
import chap9.Outer2.StaticInner;

class Outer2{
	private int outeriv = 10;
	private static int outercv=20;
	
	class InstanceInner{
		int iiv = outeriv;
		int iiv2 = outercv; //인스턴스멤버 -> 클래스멤버 (접근 가능)
	}
	
	static class StaticInner{
//		static int scv = outeriv;   클래스멤버->인스턴스멤버 (호출불가능) //객체화해야함
		static int scv = new Outer2().outeriv;
		static int scv2 = outercv;
		int siv2 = outercv;
	}
	/*
	 * 지역내부클래스에 사용되는 메서드의 지역변수는 상수화되어야함
	 * 지역변수의 변경이 없는경우는 상수로 판단함
	 * 지역변수의 변경은 안됨
	 */
	void method(int pv) {
		int lv=100;
//		lv++;지역변수의 변경은 안됨
		class LocalInner{
			int liv = outeriv;
			int liv2 = outercv;
			void method(int num) {
				System.out.println("===== LocalInner 클래스 =====");
				System.out.println("outeriv : "+outeriv);
				System.out.println("outercv : "+outercv);
				System.out.println("liv : "+ ++liv);//내부클래스의 멤버변수
				System.out.println("liv2 : "+ ++liv2);//내부클래스의 멤버변수
				System.out.println("num :  "+ ++num);//내부메서드의 지역변수 100
				System.out.println("pv : "+pv);//외부메서드의 지역변수 : 0
				System.out.println("lv : "+lv); // 외부메서드의 지역변수 . 100
			}
		}
		LocalInner l = new LocalInner();
		l.method(100);
	}
}

public class InnerEx2 {
	public static void main(String[] args) {
		Outer2 outer2 = new Outer2();
//		outer2.iv;    호출불가  private멤버
		
		//InstacneInner, StaticInner 내부의멤버출력하기
		System.out.println("===== InstanceInner 클래스 =====");
		InstanceInner i = outer2.new InstanceInner();
		System.out.println("i.iiv : "+ ++i.iiv);
		System.out.println("i.iiv2 : "+ ++i.iiv2);

		
		System.out.println("===== StaticInner 클래스 =====");
		StaticInner s = new Outer2.StaticInner();
		System.out.println("StaticInner.scv : "+Outer2.StaticInner.scv);
		System.out.println("StaticInner.scv : "+Outer2.StaticInner.scv2);
		System.out.println("s.siv2 : "+s.siv2);
		
		outer2.method(90);
		
	}
}

===== InstanceInner 클래스 =====

i.iiv : 11

i.iiv2 : 21

===== StaticInner 클래스 =====

StaticInner.scv : 10

StaticInner.scv : 20

s.siv2 : 20

===== LocalInner 클래스 =====

outeriv : 10

outercv : 20

liv : 11

liv2 : 21

num : 101

pv : 90

lv : 100

 


2-2 ) 내부클래스에서 사용되는 this , super

 

 

* 내부클래스의 멤버메서드에서 변수 접근 우선순위

 

1.지역변수

 2.내부클래스의 멤버변수 : this.멤버변수

 3.외부클래스의 멤버변수 : 외부클래스명.this.멤버변수

 4.외부클래스 부모의 멤버변수 : 외부클래스명.super.멤버변수

package chap9;

import chap9.Outer3.InstanceInner;

/*
 * 내부클래스에서 사용되는 this , super
 */
class ParentOuter{
	
	int iv = 5;
	int piv = 560;
}

class Outer3 extends ParentOuter{
	int iv = 10;
	int iv2 =20;
	class InstanceInner{
		int iv =100;
		void method() {
			int iv = 300;
			System.out.println("iv : "+iv);
			System.out.println("iv2 : "+iv2);
			System.out.println("piv : "+piv);//외부클래스의 부모클래스
			System.out.print("===지역변수 , 멤버변수 , 외부클래스의멤버변수  \n외부클래스의 상위클래스 멤버변수의");
			System.out.println(" 변수명이 모두 같다면 이렇게 접근해야한다===");
			
			//나의 멤버
			System.out.println("this.iv : "+this.iv); 
			//바깥클래스의 멤버  : 외부클래스명.this.멤버명
			System.out.println("Outer3.this.iv : "+Outer3.this.iv);
			//바깥클래스의 부모의 멤버 : 바깥클래스명.super.멤버
			System.out.println("Outer3.super.iv : "+Outer3.super.iv);
			
			//그냥 멤버명을 다르게하는게 속편하긴 하다.
		}
	}
}

public class InnerEx3 {
	public static void main(String[] args) {
		InstanceInner i = new Outer3().new InstanceInner();
		i.method();
		
	}

}

iv : 300

iv2 : 20

piv : 560

===지역변수 , 멤버변수 , 외부클래스의멤버변수

외부클래스의 상위클래스 멤버변수의 변수명이 모두 같다면 이렇게 접근해야한다===

this.iv : 100

Outer3.this.iv : 10

Outer3.super.iv : 5

 


2-3) 람다 객체에서의 this

 

package chap9;

/*
 * 람다 객체에서의 this
 */

@FunctionalInterface
interface LambdaInterface{
	void method();
}

class Outer{
	public int iv=10;

	void method() {
		final int iv = 40;//바뀌면안됨
//		iv++;\
		LambdaInterface f;
		f = ()->System.out.println("@@람다객체에서의 this@@");
		f.method();
		
		f =()->{
			System.out.println("iv : "+iv);//외부메서드의 지역변수는 상수화가 필요함
			System.out.println("this.iv : "+this.iv);//Outer클래스의 멤버변수 호출
			System.out.println("Outer.this.iv : "+Outer.this.iv);//Outer클래스의 멤버변수 호출가능
		};
		f.method();
		
		
	}
	
}
public class InnerEx4 {
	public static void main(String[] args) {
		new Outer().method();
	}
}

@@람다객체에서의 this@@

iv : 40

this.iv : 10

Outer.this.iv : 10

 

 


@@ 3) 예외처리 @@

 

 

예외 (Exception) : 대처할수있는 에러

 

* 예외처리 : 발생된 예외를 정상화하는 과정
 
 * try { }  :   
예외 발생 가능성이있는문장
 * catch(예외타입 참조변수) { } : 
try구문에서 예외발생시 호출되는 블럭
 * finally{ } : 
정상,예외 상관없이 꼭 실행
 
 * throws :   
예외처리의 다른방식(던지기)
 * throw :     
예외발생

 

package chap10;
public class ExceptionEx1 {

	public static void main(String[] args) {
		
		try {
			System.out.println(args[0]);
	
		} catch (ArrayIndexOutOfBoundsException e) {
			e.printStackTrace();//오류내용출력
			System.out.println("command라인에 파라미터값 입력하세요");
		}
		
		finally {
			System.out.println("종료");
		}
	}
}

java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0

at chap10.ExceptionEx1.main(ExceptionEx1.java:18)

command라인에 파라미터값 입력하세요

종료

 

파라미터값 입력 후(하이)

 

하이

종료


또 다른 예제

 

(  두개의 예외를 잡기  ) 

 

* 다중catch

* --한개의 try블럭에 여러개의 catch블럭 존재

* -----> try블럭에서 발생되는 예외가 여러종류인 경우 예외별 예외처리가 가능

 

 밑으로 갈수록 넓은 개념으로 catch문을 적자 

ex)

catch(ArithmeticException e){}

catch(Exception e){} 

 

예외 클래스 계층

 Throwable - Error

                   - Exception(예외클래스 의 최상단) -   RunTimeException(예외처리 생략가능)

                                                                             - 그 외 Exception (예외처리 생략불가)

package chap10;

/*
 * 정상 : 12345   3/0 : 예외발생 --> 1256
 * catch블럭 : try블럭 내부에서 예외발생시 실행되는 영역
 * 
 * 다중catch
 * --한개의 try블럭에 여러개의 catch블럭 존재
 * -----> try블럭에서 발생되는 예외가 여러종류인 경우 예외별 예외처리가 가능
 * -> 상위 예외클래스(Exceptio)은 catch들 중 하단에 배치해야 함
 */
public class ExceptionEx2 {
	public static void main(String[] args) {
//		System.out.println(1/0);
		//ArithmeticException이 발생하지만 try문 밖 이므로
		//catch할 수 없음
		
		try {
			String str = "        [ㅎㅎㅎㅎㅎ]      ";
			//trim : 공백제거하는 기능
			System.out.println(str.trim()); //NullPointerException 
			System.out.println(Integer.parseInt("44"));
			System.out.println(args[0]);//ArrayIndexOutOfBoundsException발생
			System.out.print(1);
			System.out.print(2);
			System.out.print(3/0); //여기서 예외발생 ArithmeticException
			System.out.print(4);
			} 
		catch (ArithmeticException e) {//try문 안에서 예외발생시 실행
		
			System.out.println("\n 예외 메시지 : "+e.getMessage());
			System.out.print(5);	
		}
		catch (ArrayIndexOutOfBoundsException e) { //또다른 예외를 잡을 수도 있음
			System.out.println("command라인을 입력하세요");
//			e.printStackTrace(); 예외스택을 전부출력
			System.out.println("예외 메시지  : "+e.getMessage());
		}
		catch(NumberFormatException e) {
			System.out.println("예외 메시지 : "+e.getMessage());
			System.out.println(" 숫자만 입력해주세요 !");
		}
		
		catch(Exception e ) {
			//모든 예외를 잡아줌(catch문은 위로갈수록 상세하게 잡아주는게 원칙)
			// 상위 예외클래스는 catch들 중 하단에 배치
			
			System.out.println("예외 메시지 : "+e.getMessage());
		}
		
		System.out.println(6);//예외와상관없이 실행
	}
}

[ㅎㅎㅎㅎㅎ]

44

입력완료!

12

예외 메시지 : / by zero

56


 

예외명에 마우스 갖다대고 기다린 후 브라우저 모양을 누르면 API를 볼 수 있음

 

최상위는 당연히 Object지만 상위에 Exception이 존재함을 확인

 


예제 ) 


 * 화면에서 정수형 숫자를 입력받아서 정수형 숫자인 경우 숫자만큼 * 출력하고
 * 정수형 숫자가 아닌경우 숫자만 입력하세요 메시지

package chap10;

import java.util.InputMismatchException;
import java.util.Scanner;

/*
 * 화면에서 정수형 숫자를 입력받아서 정수형 숫자인 경우 숫자만큼 * 출력하고
 * 정수형 숫자가 아닌경우 숫자만 입력하세요 메시지 후 초기화
 *InputMismatchException
 */
public class Exam2 {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);

		while(true) {
			try {
				System.out.print("정수를 입력하세요 : ");
				int num = scan.nextInt();
				
				for (int k = 0; k < num; k++) {
					System.out.printf("%4s","*");

				}System.out.println();
				break;

			} catch (InputMismatchException e) {
				System.out.println("숫자만 입력하세요 !!");	
				scan.next();
                //scan.next()로 문자를 버려주지않으면
				//nextInt()로 문자를 읽을 수 없으므로
				//Scanner 안에 문자가 계속남아  무한출력.	
			}	
		}	
	}
}

InputMismatchException은 RunTimeException 이므로 우리가 지금까지 예외처리를 하지않고 사용해 왔던 것

정수를 입력하세요 : k

예외명 : class java.util.InputMismatchException

예외 메시지 : null

숫자만 입력하세요 !!

 

정수를 입력하세요 : 8

* * * * * * * *


@@ 4) 인터페이스 , 내부클래스 문제 @@

test (2).zip
0.00MB

 

 

 

 

그나마 어려운거 몇개만 추려보겠다


문제 1)

 

구동 클래스를 실행 했을 때 다음의 결과가 나오도록 
RemoteControl 인터페이스 완성하기

[결과]
TV를 켭니다.
Tv의 볼륨을 10으로 설정합니다.
TV를 끕니다.
무음 처리합니다.
Audio를 켭니다.
Audio의 볼륨을 20으로 설정합니다.
Audio를 끕니다.
무음을 해제합니다.
건전지를 교환합니다.

package test;

interface RemoteControl {
}
class Television implements RemoteControl{
	public void turnOn() {
		System.out.println("TV를 켭니다.");
	}
	public void turnOff() {
		System.out.println("TV를 끕니다.");
	}
	public void setVolume(int volumn) {
		System.out.println("Tv의 볼륨을 "+volumn+"으로 설정합니다.");
	}
}
class Audio implements RemoteControl{
	public void turnOn() {
		System.out.println("Audio를 켭니다.");
	}
	public void turnOff() {
		System.out.println("Audio를 끕니다.");
	}
	public void setVolume(int volumn) {
		System.out.println("Audio의 볼륨을 "+volumn+"으로 설정합니다.");
	}
}

public class Test1 {
	public static void main(String[] args) {
		RemoteControl rc = new Television();
		rc.turnOn(); //TV를 켭니다.
		rc.setVolume(10); //Tv의 볼륨을 10으로 설정합니다.
		rc.turnOff(); //TV를 끕니다.
		rc.setMute(true); //무음 처리합니다.
		rc = new Audio();
		rc.turnOn(); //Audio를 켭니다.
		rc.setVolume(20); //Audio의 볼륨을 20으로 설정합니다.
		rc.turnOff(); //Audio를 끕니다.
		rc.setMute(false); //무음을 해제합니다.
		RemoteControl.changeBattery(); //건전지를 교환합니다.
	}
}

현재 인터페이스는 아예 비어있으며

인터페이스의 구현체들이 동일한

메서드를 가지고있다

 

인터페이스에

이부분은 추상메서드로 설정하면 될것같고

setMute(boolean b) 라는 default메서드 하나를 만들어주고

changeBattery()라는 static메서드 하나를 만들어주면 될 것같다

(default , static 메서드는 동일한 메서드명이 있지않으면

오버라이딩을 하지않아도 된다)

 

바꾼 인터페이스

interface RemoteControl {
	void turnOn();
	void turnOff();
	void setVolume(int volumn);
	default void setMute(boolean a) {
		if(a==true) {
        setVolume(0);
		System.out.println("무음처리");
        }
		else {
			System.out.println("무음을 해제");
		}
	}
	static void changeBattery() {
		System.out.println("건전지교체");
	}
}

예제 2)


 * LambdaInterface1 인터페이스의 함수 객체와 
 * 인터페이스를 사용한 calc 함수 구현하기


 * [결과]
 * 두수 (5,2)의 합:7
 * 두수 (5,2)의 곱:10
 * arr 배열의 최대값:10
 * arr 배열의 최소값:1

package test;

interface LambdaInterface1 {
	int method(int x, int y);
}

public class Test4 {
	public static void main(String[] args) {
		LambdaInterface1 f;
		f=(x,y)-> x+y;	
		System.out.println("두수 (5,2)의 합:" + calc(5,2,f));//7
		f=(x,y)-> x*y;	
		System.out.println("두수 (5,2)의 곱:" + calc(5,2,f));//10
		int[] arr = {1,2,3,4,5,6,7,8,9,10};
		f=(x,y)->x>y?x:y;
		System.out.println("arr 배열의 최대값:" + calc(arr,f));//10
		f=(x,y)->x<y?x:y;
		System.out.println("arr 배열의 최소값:" + calc(arr,f));//1
	}
}

일단 람다식을 활용해 LambdInterface1의

method동작 방식을 계속 바꿔가는 문제다

 

f=(x,y) -> x+y; 라는 뜻은

LambdInterface1(int x , int y )에

x y 를 넣으면   x+y 를 뽑아낸다는 뜻

 

calc(5,2,f) 가 int형으로 반환되는것으로보인다

calc(int x , int y , Lambdaface1 f){ f.method(x,y)}

의 형식으로 static void  메서드를 만들면 합과 곱은 해결

 

배열쪽이 조금 생각이 많았는데

method(x,y)가  더 큰 숫자를 반환하는 내용으로 바뀜

배열을 넣고

for문으로 요소를 뽑아낸다

그리고 max값과 min값을 구한 후

f.method( arr[max] , a[min]) 를 반환 

 

또한 메서드의 매개변수가 달라지기때문에 오버로딩을 통해 하나 더 만들어준다

 

package chap9.test;

interface LambdaInterface1 {
	int method(int x, int y);
}
public class Test4 {
	
	 static int  calc(int x , int y , LambdaInterface1 f) {
		return f.method(x, y);
	}
	 
	 static int calc(int[] a , LambdaInterface1 f) {//메서드 오버로딩 (매개변수를 다르게)
		 int max=0,min=0;
		 for (int i = 1; i < a.length; i++) {
			if(a[max]<a[i]) {
				max = i;
			}
			if(a[min]>a[i]) {
				min = i;
			}
		}
		 return f.method(a[max], a[min]);
		 
	 }
	
	public static void main(String[] args) {
		LambdaInterface1 f;
		
		f=(x,y)-> x+y;	
		System.out.println("두수 (5,2)의 합:" + calc(5,2,f));//7
		
		f=(x,y)-> x*y;	
		System.out.println("두수 (5,2)의 곱:" + calc(5,2,f));//10
		
		int[] arr = {5,8,12,3,1,24,42,14};
		
		f=(x,y)->x>y?x:y;
		System.out.println("arr 배열의 최대값:" + calc(arr,f));//10
		
		f=(x,y)->x<y?x:y;
		System.out.println("arr 배열의 최소값:" + calc(arr,f));//1
	}
}

 


예제 3)


 *  LambdaInterface2를 이용하여 1부터 100까지의 임의의 수 10개를
 *  배열에 저장하고, 그중 짝수,홀수를 구분하여 출력하고,
 *  함수 객체에 의해서 짝수의 합 또는 홀수의 합을 출력하는 numSum 메서드를 구현하기
 
 *  [결과]
    3,73,83,40,52,45,43,33,26,6,
    홀수 :3,73,83,45,43,33,=280
    짝수 :40,52,26,6,=124

package test;
interface LambdaInterface2 {
	boolean method(int a);
}
public class Test5 {
	public static void main(String[] args) {
		int[] arr = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) (Math.random() * 100) + 1;
			System.out.print(arr[i] + ",");
		}
		System.out.println();
		System.out.print("홀수의 합:");
		numSum(a -> a % 2 != 0, arr);
		System.out.print("짝수의 합:");
		numSum(a -> a % 2 == 0, arr);
	}
}

일단 알아야 할 건

numSum(a -> a%2 != 0 ,arr)의 동작방식이다

LambdaInterface2 f;

f=(a)-<{return a%2 !=0 ;};

numSum(f,arr);      과 같은거다

 

해야할건

static void 타입의 numSum (LambdaInterface2 f , int[] arr)

메서드 생성만 하면 됨

int sum=0 ; 을 만들고

for문으로 요소를 전부다 뽑을 준비를 해주고

f.method(i) 로 홀수 or 짝수를 모두 뽑아 sum변수에 넣어줌

정답

package chap9.test;
/*
 *  LambdaInterface2를 이용하여 1부터 100까지의 임의의 수 10개를
 *  배열에 저장하고, 그중 짝수,홀수를 구분하여 출력하고,
 *  함수 객체에 의해서 짝수의 합 또는 홀수의 합을 출력하는 numSum 메서드를 구현하기
 *  
 *  [결과]
    3,73,83,40,52,45,43,33,26,6,
    홀수 :3,73,83,45,43,33,=280
    짝수 :40,52,26,6,=124
 */

interface LambdaInterface2 {
	boolean method(int a);
}
public class Test5 {
	public static void main(String[] args) {
		int[] arr = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) (Math.random() * 100) + 1;
			System.out.print(arr[i] + ",");
		}
		
		
		
		System.out.println();
		System.out.print("홀수의 합:");
		LambdaInterface2 f;
		f =(a)-> {return a%2 != 0; };   //2로나눈나머지가 2가 아니면 true;
		numSum(f, arr);                //밑이랑 같은 뜻임
		
//		numSum(a -> a % 2 != 0, arr);//method(int a)를 말하는거임 method(int a)의 동작을 만든것!!
		
		
		System.out.print("짝수의 합:");
		numSum(a -> a % 2 == 0, arr);

//---------------------------------------------------------------------
		
	}
	private static void numSum(LambdaInterface2 f,int[] arr) {
		int sum=0;
		
		for (int i = 0; i < arr.length; i++) {
			if(f.method(arr[i])) {
			sum += arr[i];
			System.out.print(arr[i]+"+");
			}
		}
		System.out.println(" = "+sum); 
		
		
	}
}

 

42,60,15,4,10,98,62,59,47,62,

홀수의 합:15+59+47+ = 121

짝수의 합:42+60+4+10+98+62+62+ = 338

 

 

https://github.com/donggonyoo/javaStudyGudee/tree/main/chap9/src/chap9/test

 

javaStudyGudee/chap9/src/chap9/test at main · donggonyoo/javaStudyGudee

Contribute to donggonyoo/javaStudyGudee development by creating an account on GitHub.

github.com

풀이는 여기에 다 있음.


 

@@ 5) 인터페이스 문제( 객관식) @@

 

 

 

1. 인터페이스 내에 메서드를 적합하게 선언한 형태 2개를 고르시오.  

(1) void methoda();

(2) public double methoda(); 

(3) public final double methoda();

(4) static void methoda(double d1);

(5) protected void methoda(double d1);

(public or abstract만 가능)

 

 

2. 2번째 줄과 동일한 의미를 갖는 문장 3개를 고르시오.

1. public interface Foo {  
2. int k = 4;
3. }

(1) final int k = 4;

(2) public int k = 4;

(3) static int k = 4;

(4) abstract int k = 4;

(5) volatile int k = 4;

(6) protected int k = 4;

 

 

 

3. 다음 소스를 보고 보기 중 16라인에 추가되면

java.lang.ClassCastException을 발생시키는 문장을 선택하시오.

10. interface Foo {}										
11. class Alpha implements Foo { } 
12. class Beta extends Alpha {} 
13. class Delta extends Beta { 
14. public static void main( String[] args) { 
15. Beta x = new Beta(); 
16. // insert code here 
17. } 
18. } 

(1). Alpha a = x;

(2). Foo f= (Delta)x; 자식으로형변환????

(3). Foo f= (Alpha)x;

(4). Beta b = (Beta)(Alpha)x;

 

 

4. 다음 A 인터페이스를 상속 받아서 새로운 B 인터페이스를 생성하고자 한다. 다음 보기 중 올바른 문장을 선택하시오.

1. public interface A { 
2.    String DEFAULT_GREETING = “Hello World”; 
3.    public void method1(); 
4. } 

(1). public interface B extends A { }

(2). public interface B implements A {}

(3). public interface B instanceOf A {}

(4). public interface B inheritsFrom A { }