[ジャワの定番-基礎編Chapter 14]ジャワブルーティー


JAvaの定式-基礎編(著者南宮星)
https://www.youtube.com/watch?v=3wnmgM4qK30
関数言語
Javaはオブジェクト向け言語で、JDK 1.8から関数型言語機能が追加されました.
(関数型言語の機能を含むオブジェクト向け言語)
関数言語の例には、Haskell、Everlang、Scalaがあります.
ビッグデータの出現に伴い,関数型言語を用いて大量のデータを処理する必要がある.
PythonやJavaScriptにも関数言語の機能があります.(oop + fp)
ランダ式
  • 関数(メソッド)の簡単な表現表現表現方法
  • 例)
    int max(int a, int){
    	return a > b ? a : b;
    }
    胃の儀式.
    (a, b) -> a > b ? a : b
    簡単な作成の使用
  • 匿名関数(名前のない関数、注釈のない関数)
  • int max(int a, int b){
    	return a > b ? a: b;
    }
    int max(int a, int b) -> {
    	return a > b ? a : b;
    }
    戻りタイプと名前を削除します.
  • 関数と方法の違い
    -基本的に同じです.関数は一般的な用語で、メソッドはオブジェクト向けの概念用語です.
  • 関数はクラス(クラス内ではない)とは独立しており、メソッドはクラス(クラス内でなければならない)に依存する(Javaではメソッドのみ)
  • .
    ラムダ式の作成
  • メソッドの名前と戻りタイプを削除し、ブロック{}の前に"->"を追加します.
  • int max(int a, int b){
    	return a > b ? a: b;
    }
    ↓合成
    (int a, int b) -> {
    	return a > b ? a : b;
    }
  • の戻り値がある場合は、式または値を1つだけ書き、戻り文(末尾が「;」で貼り付けない)
  • を省略することができる.
    (int a, int b){
    	return a > b ? a : b;
    }
    ↓合成
    (int a, int b) -> a > b ? a : b
  • パラメータのタイプが推定可能(少なくない)であれば、
  • は省略可能(多くの場合省略可能)である.
    (int a, int b) -> a > b ? a : b
    ↓合成
    (a, b) -> a > b ? a : b
    ラムダ式の作成-注意事項
  • パラメータが1つしかない場合は、カッコ()(タイプがない場合のみ)
  • を省略できます.
    (a) -> a * a
    (int a) -> a * a
    ↓合成
    a -> a * a		// 가능
    int a -> a * a	// 에러 => (int a) -> a * a , 타입을 생략가능하지 않은 경우도 있어서 괄호 생략 불가
  • ブロックに文が1つしかない場合は、
  • を省略することができます(末尾は";"は加算しません)
    (int i) -> {
    	System.out.println(i);
    }
    ↓合成
    (int i) -> System.out.println(i)
    ただし、return文が1つしかない場合は、括弧=>を省略することはできません.
    (int a, int b) -> { return a > b ? a : b; }		// 가능
    (int a, int b) ->  return a > b ? a : b			// 에러
    (int a, int b) -> a > b ? a : b   				// return 생략해서 작성
    ランダ式の例
    メソッドram式int max(int a,int b){  return a > b ? a : b ;}(a, b) -> a > b ? a : bint printVar(String name, int i){  System.out.println(name+"="+i) ;}(name, i) -> System.out.println(name+"="+i)int square(int x){  return x * x ;}x -> x * xint roll(){  return (int)(Math.random()*6) ; }( ) -> (int)(Math.random( ) * 6)
    ラムド式は匿名関数ですか?匿名のオブジェクト!
  • ラム多項式は匿名関数ではなく匿名オブジェクトである.
    -Javaではメソッドのみが存在しないためです.したがって、Javaでは匿名オブジェクト
  • ラムダ式
    (a, b) -> a > b ? a : b

    匿名クラス内の匿名オブジェクト
    new Object(){
    	int max(int a, int b){
        	return a > b ? a : b;
        }
    }
    匿名クラス内の匿名オブジェクト.オブジェクトの同時宣言と作成
  • ブルーマルチ(匿名オブジェクト)を処理するために参照変数が必要です.参照変数のタイプは?
  • Object obj = new Object(){
    	int max(int a, int b){
        	return a > b ? a : b;
        }
    };
    타입 obj(참조변수) = (a, b) -> a > b ? a : b	// 어떤 타입?
    
    int value = obj.max(3,5);	// 에러. Object 클래스에  max()가 없어서 호출/사용 불가
    関数インタフェース
  • 関数インタフェース-1つの抽象メソッドのみが宣言するインタフェース
  • 関数インタフェース宣言
    interface MyFunction{
    	public abstract int max(int a, int b);	// 함수형 인터페이스
    }
    上記インタフェースを実装と、
    MyFunction f = new MyFunction() { // 익명 클래스. 클래스의 선언, 객체 생성을 동시에 함
    				public int max(int a, int b){
                    	return a > b ? a : b;
                    }
    			 }
    新しい祖先クラス名(クラスまたはインタフェース){メンバー}
    オブジェクトタイプではなく、関数インタフェースを作成して使用します.
    int value = f.max(3,5);		// 가능. MyFunction에 max()가 있음
  • 関数型界面タイプの参照変数は、ラム多項式を参照することができる
    -ただし、関数型インタフェースの方法とram多項式のパラメータ個数と戻りタイプは一致しなければならない.
  • ランダ式
    MyFunction f = (a, b) -> a > b ? a : b;
    int value = f.max(3,5); 	// 실제로는 람다식(익명 함수)이 호출됨
  • 関数型インタフェースはramda式を処理するために使用される.
  • コードの例
    public class Ex14_0 {
    	public static void main(String[] args) {
    	//	Object obj = (a, b) -> a > b ? a : b	// 람다식. 익명 객체
    		Object obj = new Object(){
    			int max(int a, int b){
    				return a > b? a: b;
    			}
    		};
    		
    	//	int value = obj.max(3,5);	// 호출 불가. Object에는 max()가 없음
    									// Object 타입이 아닌 다른 타입이 필요함
    									// 함수형 인터페이스가 필요함
    	
    	// 함수형 인터페이스를 사용
    //	MyFunction f = new MyFunction() {
    //		
    //		@Override
    //		public int max(int a, int b) {	// 오버라이딩 - 접근 제어자는 좁게 못바꾼다.
    //			return a > b? a: b;
    //		}
    //	};
    	
    	// 위의 코드를 짧게 람다식 사용
    	// 람다식(익명개체)을 다루기 위한 참조변수의 타입은 함수형 인터페이스로 한다.	
    	// 람다식과 함수형 인터페이스에 선언된 추상메서드와 매개변수의 타입,개수와 결과타입이 같아야 한다.	
    	// 람다식은 메서드인데 호출하려면 이름이 필요하다. 람다식에서는 이름을 없앴지만 추상메서드로 이름을 붙여준다.
    	// 추상메서드를 통해서 람다식을 호출
    	MyFunction f = (a, b) -> a > b ? a : b;	// 람다식은 익명 객체이기 때문에 참조 변수가 필요하다
    											// 참조변수의 타입은 함수형 인터페이스 타입
    
    	int value = f.max(3, 5);
    	System.out.println("value="+value);
    	
    	}
    }
    						
    					   // FunctionalInterface : 함수형 인터페이스라는 뜻
    					   // 붙여주면 추상 메서드가 2개 이상일 시 오류. 
    					   // 안붙이면 여러개 가능하지만 추상 메서드는 하나만 가져아하니까
    					   // 컴파일러가 알아서 체크해줌
    @FunctionalInterface   // 함수형 인터페이스는 단 하나의 추상 메서드만 가져야 함. 
    interface MyFunction{
    //	public abstract int max(int a, int b);
    	int max(int a, int b);	// public abstract는 생략 가능
    	// 람다식(메서드)를 호출하기 위한 이름을 붙임 : max
    }
    関数インタフェース-example
  • 匿名オブジェクト
  • をランダ形式で置換
    以前に作成したコード
    List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
    
    Collections sort(list, new Comparator<String>(){
    		           public int compare(String s1, String s2){
    				return s2.compareTo(s1);
                       }
                           )}; 
    関数インタフェース
    interface Comparator<T>{
    	int compare(T o1, T o2);
    }
    ランダ式
    List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
    Collections.sort(list, (s1, s2) -> s2.compareTo(s1));
    sort(List list, Comparator c)
    関数インタフェースタイプのパラメータ、戻りタイプ
  • 関数型インタフェースタイプのパラメータ
  • void aMethod(MyFunction f){
    	f.myMethod();	// MyFunction 인터페이스에 정의된 메서드 호출
    }
    aメソッド()のパラメータは、ラムダ式を受け入れることを示す
    関数インタフェース
    @FunctionalInterface
    interface MyFunction{
    	void myMethod();	// 람다식(메서드)의 이름을 붙여줌
    }
    呼び出しaメソッド()
    MyFunction f = () -> System.out.println("myMethod()");	// 람다식을 참조변수에 담음
    aMethod(f);		// 참조변수를 넣어줌
    上の2つの文を合わせる
    aMethod(() -> System.out.println("myMethod()"));	// 참조변수 없이 람다식을 직접 넣음
  • 関数型インタフェースタイプの戻りタイプ
  • MyFunction myMethod(){
    	MyFunction f = () -> {};
        return f;
    }
    mymethod()メソッドはramda式を返します.
    上のコードのサムネイル
    MyFunction myMethod(){
    	return () -> {};
    }
    サンプルコード
    @FunctionalInterface
    interface MyFunction{
    	void run();	// = public abstract void run();
    }
    
    class Ex14_1 {
    	
    	// 매개변수의 타입이 MyFunction인 메서드
    	static void execute(MyFunction f){	
    		f.run();
    	}
    	
    	// 반환 타입이 MyFunction인 메서드
    	static MyFunction getMyFunction(){	
    //		MyFunction f = () -> System.out.println("f3.fun()");
    //		return f;
    		
    		// 위의 코드를 줄이면
    		return () -> System.out.println("f3.fun()");
    	}
    	
    	public static void main(String[] arg){
    		// 람다식으로 MyFunction의 run()을 구현
    		MyFunction f1 = () -> System.out.println("f1.run()");
    		
    		// 익명 클래스로 run()을 구현
    		// 함수형 인터페이스를 직접 구현
    		MyFunction f2 = new MyFunction() {
    			
    			@Override
    			public void run() {	// public을 반드시 붙여야 함
    				System.out.println("f2.run()");
    			}
    		};
    		
    		MyFunction f3 = getMyFunction();
    //		MyFunction f3 = () -> System.out.println("f3.fun()"); 이라는 것
    		
    		f1.run();
    		f2.run();
    		f3.run();
    		
    		execute(f1);
    		
    		// 람다식을 직접 매개변수로 넘겨줌
    		execute( ()-> System.out.println("run()") );
    	}
    }