JAVA 4 01ラムティー


リンクテキスト

Lambda Expression


定義#テイギ#

  • 関数を簡単な表現で表す方法
  • 匿名関数、無名関数、anonymous function
  • 関数とメソッドの違い

  • まったく同じ
  • 関数は共通用語で、方法は対象向けの概念用語
  • 関数はクラスに依存せず、メソッドはクラスに依存する
  • 生成方法

  • 消去方法名と返却タイプ、->実施部ブロック{}の前に追加する.
  • int max(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
  • パラメータタイプが推定可能であれば省略可能(大部分省略)
  • ->
    (a, b) -> a > b ? a : b

    注意事項

  • パラメータは1つのみ:括弧()は省略可能(タイプがない場合のみ)
  • a -> a * a		//(O)
    (int a) -> a * a	//(O)
    
    (a) -> a * a		//(O)
    int a -> a * a		//(X)
  • 実施部ブロック内の文が一体の場合:括弧省略可;省略不可
  • (int i) -> System.out.println(i)
  • 回文を省略しない場合:括弧
  • (int a, int b) -> { return a > b ? a : b }	//(O)
    (int a, int b) -> a > b ? a : b			//(O)
    
    (int a, int b) -> return a > b ? a : b		//(X)

    はい。

    
    	//메소드 -> 람다식으로 바꿔보자
    	//1.
    	int max(int a, int b) {
    		return a > b ? a : b;
    	}
    	//->
    	(a, b) -> a>b ? a:b
    			
    	//2
    	void printVar(String name, int i) {
    		System.out.println(name+ "="+i);
    	}
    	//->
    	(name, i) -> System.out.println(name+"="+i)
    	
    	//3
    	int square(int x) {
    		return x*x;
    	}
    	//->
    	x -> x*x
    	
    	
    	//4
    	int roll() {
    		return (int)(Math.random()*6);
    	}
    	//->***매개변수가 없을 땐 괄호()생략 안됨!!
    	() -> (int)(Math.random()*6)

    蓝多式は匿名の対象です!!


  • 汚染汚染汚染多食は匿名関数ではなく、匿名対象!

  • 上記の例のランダ式は以下の通りです.
  • new Object() {
    	int max(int a, int b) {
    		return a > b ? a : b;
    	}
    }

  • そのため、参考変数として扱うべきです!!

  • 匿名クラス宣言、オブジェクトの同時作成方法
  • new 조상클래스/인페명 { ... };
    しかし
    	Object obj = new Object() {
    		int max(int a, int b) {
    			return a>b ? a:b;
    		}
    	};
    	
    	int value = obj.max(3, 5);
  • 📢📢問題が発生!
    -> 1. タイプを選択するには、どうすればいいですか?
    -> 2. The target type of this expression must be a functional interface.
  • この問題を解決するのは関数型インタフェースです!!
    つまり、ram多項式を関数型インタフェースタイプの参照変数として使用する必要があります!

    関数インタフェース

  • 抽象メソッド宣言が1つしかないインタフェース
  • 1.

    @FunctionalInterface
    interface MyFunction {
    	public abstract int max(int a, int b);
    }

    2.


    +匿名クラスを直接実装

    MyFunction f = new MyFunction() {
    	public int max(int a, int b) {
    		return a > b ? a : b;
    	}
    };
    //**(O) MyFunction에 max()가 있으니까!
    int value = f.max(3, 5);

    +ラムティー

    MyFunction f = (a, b) -> a > b? a : b;
    int value = f.max(3, 5);
    //실제로는 람다식(익명함수)이 호출됨
    ex14_00
    
    class Ex14_00 {
    	
    	public static void main(String[] args) {
    		//익명클래스로 직접 구현
    		MyFunction2 f = new MyFunction2() {
    			@Override
    			public int max(int a, int b) {	//***public!!
    				return a>b? a:b;
    			}
    		};//MF
    		int value = f.max(3, 5);
    		System.out.println("value= "+value);
    		
    		//람다식***
    		MyFunction2 f2 = (a, b) -> a>b? a:b;
    		int value2 = f2.max(3, 5);
    		System.out.println("value2= "+value2);
    	}//main
    
    }
    
    @FunctionalInterface
    interface MyFunction2{
    	public abstract int max(int a, int b);
    }
    value= 5
    value2= 5

    関数式の入出力式を利用したComparator

  • Comparatorは機能インタフェースとしても良いのでしょうか?

  • ますます書くのがおっくうになってきた...ほほほ
    Comparator, Comparable, sort()
    ex14_001
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    public class Ex14_001 {
    
    	public static void main(String[] args) {
    		List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
    		Collections.sort(list, (s1, s2) -> s2.compareTo(s1));
    //		Collections.sort(list, new Comparator<T>() {
    //			public int compare(String s1, String s2) {
    //				if(s1 instanceof Comparable && s2 instanceof Comparable) {
    //					Comparable c1 = (Comparable) s1;
    //					Comparable c2 = (Comparable) s2;
    //					return s2.compareTo(s1);	//역순
    //				}
    //				return -1;
    //			}
    //		});
    		//이 방식은 자꾸 에러나서 못하겠다 ㅠㅠㅠ
    		System.out.println("list = "+list);
    
    	}
    
    }
    //기본적으로 이렇게 되어있어, 아래가 없어도 작동한다!
    @FunctionalInterface
    interface Comparator<T>{
    	public abstract int compare(T o1, T o2);
    }
    list = [ddd, bbb, abc, aaa, aaa]
    ex 11 07を追加
    import java.util.Arrays;
    import java.util.Comparator;
    
    public class Ex11_07 {
    
    	public static void main(String[] args) {
    		String[] strArr = {"cat", "Dog", "lion", "tiger"};
    		
    		Arrays.sort(strArr, (s1, s2) -> s2.compareTo(s1));
    		System.out.println("strArr = "+Arrays.toString(strArr));
    
    		Arrays.sort(strArr, new Descending());
    		//이번엔 직접 만든 기준을 담은 객체를 호출한다.+역순
    		System.out.println("strArr = "+Arrays.toString(strArr));
    		
    	}
    
    }
    //마찬가지!! 아래가 없어도 잘 작동함
    @FunctionalInterface
    interface Comparator1{
    	public abstract int compare(Object o1, Object o2);
    }
    
    //둘다 되는데 뭐가 맞는지 모르겠다.
    @FunctionalInterface
    interface Comparator1<T>{
    	public abstract int compare(T o1, T o2);
    
    //기존의 compare()를 역순을 배출하는 메소드로 오버라이딩하기
    //따라서 compare()를 갖고 있는 Comparator를 구현해야 한다.
    class Descending implements Comparator{
    	public int compare(Object o1, Object o2) {
    		//Comparable이 o1, o2의 조상타입클래스 또는 구현된인터페이스라면
    		//이 문제에선, String implements Comparable 이므로 true
    		//왜 Comparable?? : compareTo()를 쓰려고
    		if(o1 instanceof Comparable && o2 instanceof Comparable) {
    			Comparable c1 = (Comparable)o1;
    			Comparable c2 = (Comparable)o2;
    			return c1.compareTo(c2) * -1;
    //			return c2.compareTo(c1);
    		}
    		return -1;	
    		//비교대상이 Comparable을 구현한 클래스가 아니면 비교할 수 없기에 
    		//참고로 String은 Comparator를 구현하지 않았다!! Comparable만!!!
    	}
    }
    strArr = [Dog, cat, lion, tiger]
    strArr = [cat, Dog, lion, tiger]
    strArr = [tiger, lion, cat, Dog]
    strArr = [tiger, lion, cat, Dog]

    関数インタフェース


    関数インタフェースタイプのパラメータ



    1.

  • ラム多式を持つ関数型インタフェースを受け入れる(MyFunction)パラメータとしての方法
  • ラム茶食を(myMethod())ラム茶食と命名する方法(aMethod()).
  • 2.

  • ラムダ式を呼び出す方法のパラメータにラムダ式を作成する.
  • 関数型インタフェースタイプの戻りタイプ


  • ラム多式付き関数型インタフェース(MyFunction)戻りタイプメソッド
  • その方法(myMethod())内で、戻りタイプにラムダ式を記入します.
  • リンクテキスト
    ex14_01
    
    public class Ex14_01 {
    
    	public static void main(String[] args) {
    		//1. 익명클래스로
    		MyFunction f1 = new MyFunction() {
    			@Override
    			public void run() {
    				System.out.println("f1.run!");
    			}
    		};
    		f1.run();
    		
    		//2. 람다식으로
    		MyFunction f2 = () -> System.out.println("f2.run!!");
    		f2.run();
    		
    		//3. 함수형인페를 매개변수로 삼고, 람다식을 호출하는 메소드
    		MyFunction f3 = () -> System.out.println("f3.run!!!");
    		execute(f3);	//이 두줄을 줄이면
    		execute(() -> System.out.println("f3.run!!!"));
    		
    		//4. 함수형인페가 반환타입, 람다식을 뱉어내는 메소드
    		MyFunction f4 = getMyFunction();
    		f4.run();
    		//이렇게 바로도 된다!
    		getMyFunction().run();
    		
    
    	}//main
    	
    	static void execute(MyFunction f) {
    		f.run();	//람다식을 호출하는 메소드
    	}
    	
    	static MyFunction getMyFunction() {
    //		MyFunction f = () -> System.out.println("f4.run!!!!");
    //		return f;
    		return () -> System.out.println("f4.run!!!!");
    	}
    
    }
    
    @FunctionalInterface
    interface MyFunction{
    	void run();
    }
    f1.run!
    f2.run!!
    f3.run!!!
    f3.run!!!
    f4.run!!!!
    f4.run!!!!

    Ref

  • 生活コードJAVA 1
  • オブジェクト化の説明
  • w3schools JAVA
  • 羅東彬
  • ジャワけっしょうせき
  • ジャワ議政石羽バニラ
  • クラスとオブジェクト