Java

λžŒλ‹€Lambda

voider 2020. 9. 9. 11:01

πŸ“š μžλ°”μ˜ 정석을 μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.

β–ͺ λžŒλ‹€μ‹Lambda Expression

μžλ°”λŠ” 두 번의 큰 λ³€ν™”κ°€ μžˆμ—ˆλ‹€. JDK1.5의 μ§€λ„€λ¦­μŠ€. JDK1.8의 λžŒλ‹€.
λžŒλ‹€μ˜ λ“±μž₯으둜 객체지ν–₯μ–Έμ–΄λ₯Ό λ„ˆλ¨Έ ν•¨μˆ˜ν˜• μ–Έμ–΄κ°€ 가진 κΈ°λŠ₯κΉŒμ§€ κ°–μΆ”κ²Œ λ˜μ—ˆλ‹€.
λ§ν•˜μžλ©΄ λΉ„λ‘œμ†Œ 호λͺ¨ μ‚¬ν”Όμ—”μŠ€μ˜ 길에 μ ‘μ–΄λ“  κ²ƒμΌκΉŒ?

λžŒλ‹€μ‹μ΄λž€ κ°„λ‹¨νžˆ λ©”μ„œλ“œλ₯Ό ν•˜λ‚˜μ˜ μ‹μœΌλ‘œ ν‘œν˜„ν•œ 것이닀.
ν•¨μˆ˜λ₯Ό κ°„λž΅ν•˜λ©΄μ„œλ„ λͺ…ν™•ν•œ μ‹μœΌλ‘œ νŽΈν•  수 μžˆλ‹€.

λ©”μ„œλ“œλ₯Ό λžŒλ‹€μ‹μœΌλ‘œ ν‘œν˜„ν•˜λ©΄ λ°˜ν™˜ 값이 없어진닀. κ·Έλž˜μ„œ 읡λͺ… ν•¨μˆ˜λΌκ³  λΆ€λ₯΄κΈ°λ„ ν•œλ‹€.

κ·Έλž˜μ„œ μ–΄λ–»κ²Œ μ“°λŠ” 거냐면.

int max(int a, int b) {
    return a > b ? a:b;
}

두 값을 μž…λ ₯λ°›κ³  큰 값을 λ°˜ν™˜ν•˜λŠ” maxλΌλŠ” λ©”μ„œλ“œκ°€ μžˆλ‹€.
이것을 λžŒλ‹€λ‘œ λ³€ν™˜ν•˜λ©΄ μ΄λ ‡κ²Œ μ“Έ 수 μžˆλ‹€.

(int a, int b) -> a > b ? a : b

//λ§€κ°œλ³€μˆ˜ νƒ€μž…μ΄ 같은 경우 νƒ€μž…μ„ μƒλž΅ν•  수 μžˆλ‹€.
(a,b) -> a > b ? a:b

μ΄λ ‡κ²Œ λ°˜ν™˜κ°’μ΄ μžˆλŠ” 경우 return문을 μ‹μœΌλ‘œ λŒ€μ²΄ν•  수 μžˆλ‹€. μ—°μ‚° κ²°κ³Όλ₯Ό returnν•œλ‹€.
λ¬Έμž₯이 μ•„λ‹ˆλΌ '식expression'μ΄λ―€λ‘œ ';'을 뢙이지 μ•ŠλŠ”λ‹€.
λ§Œμ•½, λ§€κ°œλ³€μˆ˜κ°€ ν•˜λ‚˜λΌλ©΄ λ§€κ°œλ³€μˆ˜λ₯Ό κ°μ‹ΈλŠ” κ΄„ν˜Έλ„ μƒλž΅ν•  수 μžˆλ‹€.

i -> i * i

λ©”μ„œλ“œ -> λžŒλ‹€

Method Lambda
int max(int a, int b) {
return a > b ? a : b ;
}
(a,b)-> a > b ? a : b
void 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 * x
int roll() { return (int)(Math.random()*6);} ()->(int)(Math.random() * 6)
int sumArr(int[] arr) {
int sum=0;
for(int i : arr){sum += i;}
return sum;
}
(int[] arr) -> {
int sum = 0;
for(int i : arr){ sum += i;}
return sum;
}

β–ͺ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€Functional Interface

λžŒλ‹€λŠ” 읡λͺ… 클래슀 객체와 λ™λ“±ν•˜λ‹€.

new Object() {
    int max(int a, int b) {
        return a > b ? a : b;
    }
}

이 μ½”λ“œμ™€

(a,b) -> a > b ? a : b ;

이 μ½”λ“œκ°€ λ™λ“±ν•˜λ‹€λŠ” λœ»μ΄λ‹€.

κ·Έλ ‡λ‹€λ©΄ λžŒλ‹€λ‘œ μ •μ˜λœ 읡λͺ… 객체의 λ©”μ„œλ“œλ₯Ό μ–΄λ–»κ²Œ ν˜ΈμΆœν•˜λ €λ©΄ 객체의 μ£Όμ†Œλ₯Ό μ €μž₯ν•  μ°Έμ‘°λ³€μˆ˜κ°€ ν•„μš”ν•˜λ‹€.

νƒ€μž… f = (int a, int b) -> a > b ? a : b;

μ–΄λ–€ νƒ€μž…μ΄ 올 수 μžˆμ„κΉŒ?

쑰건

  • λžŒλ‹€μ‹κ³Ό 같은 λ©”μ„œλ“œκ°€ μ •μ˜λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€.
    κ·Έλž˜μ•Όλ§Œ μ°Έμ‘°λ³€μˆ˜λ₯Ό μ΄μš©ν•΄ λžŒλ‹€μ‹μ„ ν˜ΈμΆœν•  수 μžˆλ‹€.
interface MyFuntion {
    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 big = f.max(5,3);

μœ„ 읡λͺ…ν΄λž˜μŠ€λ₯Ό λžŒλ‹€λ‘œ λŒ€μ²΄ν•  수 μžˆλ‹€.

MyFunction f = (a, b) -> a > b ? a : b;    
int big = f.max(5,3);    //λ©”μ„œλ“œ 호좜

읡λͺ…객체λ₯Ό λžŒλ‹€λ‘œ λŒ€μ²΄ κ°€λŠ₯ν•œ μ΄μœ λŠ” λžŒλ‹€μ‹λ„ μ‹€μ œλ‘œλŠ” 읡λͺ… 객체이기 λ•Œλ¬Έμ΄λ‹€.
ν•˜λ‚˜μ˜ λ©”μ„œλ“œκ°€ μ„ μ–Έλœ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•œ λ‹€μŒ λžŒλ‹€λ₯Ό λ‹€λ£¨λŠ” 것은 기쑴의 μžλ°” κ·œμΉ™μ„ 어기지 μ•ŠμœΌλ©΄μ„œ μžμ—°μŠ€λŸ½λ‹€.
κ·Έλž˜μ„œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 λžŒλ‹€λ₯Ό 닀루기 μ‹œμž‘ν–ˆλ‹€. 이런 μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€functional interface라고 ν•œλ‹€. μΈν„°νŽ˜μ΄μŠ€ 선언뢀에 λ‹¨μˆœνžˆ μ–΄λ…Έν…Œμ΄μ…˜ ν•˜λ‚˜ μΆ”κ°€ν•˜λŠ” 것 λ§κ³ λŠ” κΈ°μ‘΄κ³Ό λ‹€λ₯΄μ§€ μ•Šλ‹€. μœ„ 짧은 μ˜ˆμ œμ—μ„œ λ³΄μ•˜λ“―μ΄ 없어도 상관은 μ—†μ§€λ§Œ μ»΄νŒŒμΌλŸ¬μ—μ„œ ν™•μΈν•΄μ£Όλ―€λ‘œ λΆ™μ΄λŠ” 것이 μ’‹λ‹€.

@FunctionalInterface

  • 였직 ν•˜λ‚˜μ˜ μΆ”μƒλ©”μ„œλ“œλ§Œ μ •μ˜ν•  수 μžˆλ‹€.
    μΈν„°νŽ˜μ΄μŠ€μ˜ λ©”μ„œλ“œμ™€ λžŒλ‹€λ₯Ό 1:1둜 μ—°κ²°ν•˜κΈ° μœ„ν•΄μ„œ.

  • staticλ©”μ„œλ“œμ™€ defaultλ©”μ„œλ“œμ˜ κ°œμˆ˜λŠ” μ œμ•½μ΄ μ—†λ‹€.

읡λͺ… ν΄λž˜μŠ€μ™€ λžŒλ‹€ 비ꡐ

//읡λͺ… 클래슀
Collections.sort(list, new Comparator<String>() {
    public int compare(String s1, String s2) {
        return s2.compareTo(s1);
    }
}

//λžŒλ‹€
Collections.sort(list, (s1, s2) -> s2.compareTo(s1))

FunctionalInterfaceνƒ€μž… λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜νƒ€μž…

  • λ©”μ„œλ“œμ˜ λ§€κ°œλ³€μˆ˜κ°€ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€νƒ€μž…μ΄λ©΄, 호좜 μ‹œ λžŒλ‹€(λ˜λŠ” μ°Έμ‘°λ³€μˆ˜)λ₯Ό 인자둜 μž…λ ₯ν•΄μ•Ό ν•œλ‹€.

    @FunctionalInterface 
    interface MyFunction {
        void myMethod();    //μΆ”μƒλ©”μ„œλ“œ
    }
    
    ...
    void aMethod(MyFunction f) {
        f.myMethod();
    }
    -----------------------------------------
    //κ΅¬ν˜„κ³Ό λ™μ‹œμ— 호좜
    aMethod(() -> System.out.println("myMethod()"));    
  • λ°˜ν™˜νƒ€μž…μ΄ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€νƒ€μž…μ΄λΌλ©΄, λžŒλ‹€λ₯Ό returnν•œλ‹€.

    MyFunction myMethod() {
        //λ°˜ν™˜νƒ€μž…μ΄ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λΌλ©΄, λžŒλ‹€λ₯Ό returnν•œλ‹€.
        return () -> System.out.println("myMethod()");
    }

β™» λžŒλ‹€μ‹ νƒ€μž…κ³Ό ν˜•λ³€ν™˜

λžŒλ‹€μ˜ νƒ€μž…μ΄ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ νƒ€μž…κ³Ό μΌμΉ˜ν•˜λŠ” 것은 μ•„λ‹ˆλ‹€. λ‹€λ§Œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‘œ λžŒλ‹€λ₯Ό μ°Έμ‘°ν•˜λŠ” 것 뿐이닀. λžŒλ‹€μ‹μ€ 읡λͺ… κ°μ²΄μ΄λ―€λ‘œ νƒ€μž…μ΄ μ—†λ‹€.

MyFunction f = (MyFunction)(() ->{}); //μΈν„°νŽ˜μ΄μŠ€ νƒ€μž…κ³Ό, λžŒλ‹€ νƒ€μž…μ΄ λ‹€λ₯΄λ―€λ‘œ ν˜•λ³€ν™˜ ν•„μš”

ν•˜μ§€λ§Œ μ—­μ‹œ μ»΄νŒŒμΌλŸ¬κ°€ λŒ€μ‹  ν•΄μ€€λ‹€.
λžŒλ‹€λŠ” μ΄λ¦„λ§Œ 없을 뿐 객체닀. κ·ΈλŸ¬λ‚˜ Objectνƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ ν•  수 μ—†λ‹€.
ꡳ이 ν•˜λ €λ©΄ λ¨Όμ € MyFunction으둜 ν˜•λ³€ν™˜ν•΄μ•Ό ν•œλ‹€.

Object obj = ((Object)(MyFunction))(()->{})).toString();

β†— μ™ΈλΆ€ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” λžŒλ‹€μ‹

λžŒλ‹€μ‹λ„ 읡λͺ… κ°μ²΄μ΄λ―€λ‘œ 외뢀에 μ„ μ–Έλœ λ³€μˆ˜μ— μ ‘κ·Όν•˜λŠ” 방식은 읡λͺ…ν΄λž˜μŠ€μ™€ λ™μΌν•˜λ‹€.

package com.javaex.lambda;

public class LambdaEx3 {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();

        inner.method(100);
    }
}


@FunctionalInterface
interface MyFunction{
    void myMethod();
}

class Outer {
    int val = 10;   //Outer.this.val

    class Inner {
        int val = 20;   //this.val

        void method(int i) {    //(final int i)
            int val = 30;   //final int val = 30;
//            i = 10;       //finalμ΄λ―€λ‘œ λ³€κ²½ λΆˆκ°€

            MyFunction f = () -> {
                System.out.println("i : "+ i);
                System.out.println("val : " + val);
                System.out.println("this.val : " + ++this.val);
                System.out.println("Outer.this.val : " + Outer.this.val);
            };

            f.myMethod();
        }
    }
}

λžŒλ‹€μ‹ λ‚΄μ—μ„œ μ°Έμ‘°ν•˜λŠ” μ§€μ—­λ³€μˆ˜λŠ” final이 뢙지 μ•Šμ•˜μ–΄λ„ final둜 κ°„μ£Όν•œλ‹€.

πŸ“¦ java.util.function

λ©”μ„œλ“œ νŒ¨ν„΄μ€ λŒ€κ°œ λΉ„μŠ·ν•˜λ‹€.

  • λ§€κ°œλ³€μˆ˜κ°€ μ—†κ±°λ‚˜, ν•˜λ‚˜ λ˜λŠ” 두 개
  • return은 μžˆκ±°λ‚˜ μ—†κ±°λ‚˜
    μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜λ©΄ λ°˜ν™˜νƒ€μž…λ„ 문제 λ˜μ§€ μ•ŠλŠ”λ‹€.

java.util.packageμ—λŠ” 자주 μ“°μ΄λŠ” ν˜•μ‹μ˜ λ©”μ„œλ“œλ“€μ΄ μ •μ˜λ˜μ–΄ μžˆλ‹€. 늘 μƒˆλ‘œμš΄ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ“°λŠ” 것보닀 이 νŒ¨ν‚€μ§€μ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν™œμš©ν•˜λŠ” 것이 λ©”μ„œλ“œ 이름 톡일, μž¬μ‚¬μš©μ„±, μœ μ§€λ³΄μˆ˜ μΈ‘λ©΄μ—μ„œ λͺ¨λ‘ μ’‹λ‹€.

λ§€κ°œλ³€μˆ˜κ°€ ν•˜λ‚˜μΈ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

이미지 좜처 : μžλ°”μ˜ 정석

4개의 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€κ°€ μžˆλ‹€.

μ‘°κ±΄μ‹μ—μ„œ Predicate

PredicateλŠ” Function의 λ³€ν˜•μ΄λ‹€. λ°˜ν™˜κ°’μ΄ booleanμ΄λΌλŠ” 점이 λ‹€λ₯΄λ‹€. μˆ˜ν•™μ—μ„œ true λ˜λŠ” falseλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό Predicate라고 λΆ€λ₯Έλ‹€. 쑰건식을 λžŒλ‹€μ‹μœΌλ‘œ ν‘œν˜„ν•  λ•Œ μ‚¬μš©ν•œλ‹€.

Predicate<String> isEmptyStr = s -> s.length() == 0;
String s = "";

if(isEmptyStr.test(s)) {    //if(s.length() == 0)
    ....
}

λ§€κ°œλ³€μˆ˜κ°€ 두 개인 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

이미지 좜처 : μžλ°”μ˜ 정석

BiSupplierκ°€ μ—†λŠ” μ΄μœ λŠ” λ§€κ°œλ³€μˆ˜λŠ” μ—†κ³  λ°˜ν™˜κ°’λ§Œ μ‘΄μž¬ν•˜λŠ”λ° λ©”μ„œλ“œλŠ” 두 개의 값을 λ°˜ν™˜ν•  수 μ—†κΈ° λ•Œλ¬Έμ΄λ‹€.

λ§Œμ•½ 이 외에 두 개 μ΄μƒμ˜ λ§€κ°œλ³€μˆ˜λ₯Ό κ°€μ§€λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€κ°€ ν•„μš”ν•˜λ‹€λ©΄ 직접 λ§Œλ“€μ–΄ 써야 ν•œλ‹€.

@FunctionalInterface
interface TriFunction<T,U,V,R> {
    R apply(T t, U u, V v);
}

UnaryOperator와 BinaryOperator

Function의 또 λ‹€λ₯Έ λ³€ν˜•μ΄λ‹€. λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…κ³Ό λ°˜ν™˜νƒ€μž…μ΄ μΌμΉ˜ν•œλ‹€λŠ” 점이 λ‹€λ₯΄λ‹€.

CollectionFramework & Functional Interface

μ»¬λ ‰μ…˜ ν”„λ ˆμž„μ›Œν¬ μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλœ λ””ν΄νŠΈ λ©”μ„œλ“œ 쀑 μΌλΆ€λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•œλ‹€.

Interface Method μ„€λͺ…
Collection boolean removeAll(Predicate<E> filter) 쑰건에 λ§žλŠ” μš”μ†Œ μ‚­μ œ
List void replaceAll(UnaryOperator<E> operator) λͺ¨λ“  μš”μ†Œλ₯Ό λ³€ν™˜ν•˜μ—¬ λŒ€μ²΄
Iterable void forEach(Consumer<T> action) λͺ¨λ“  μš”μ†Œμ— μž‘μ—… action을 μˆ˜ν–‰
Map V compute(K key, BiFunction<K,V,V> f)
V computeIfAbsent(K key, Function<K,V> f)
V computeIfPresent(K key Function<K,V> f)
V merge(K key, V value, BiFunction<V,V,V> f)
void forEach(BiConsumer<K,V> action)
void replaceAll(BiFunction<K,V,V> f)
μ§€μ •ν•œ ν‚€μ˜ 값에 μž‘μ—… fλ₯Ό μˆ˜ν–‰
ν‚€κ°€ μ—†μœΌλ©΄ μž‘μ—… f μˆ˜ν–‰ ν›„ μΆ”κ°€
μ§€μ •ν•œ ν‚€κ°€ μžˆμ„ λ•Œ μž‘μ—… f μˆ˜ν–‰
λͺ¨λ“ μš”μ†Œμ— λ³‘ν•©μž‘μ—… fλ₯Ό μˆ˜ν–‰
λͺ¨λ“  μš”μ†Œμ— μž‘μ—… action을 μˆ˜ν–‰
λͺ¨λ“  μš”μ†Œμ— μΉ˜ν™˜μž‘μ—… fλ₯Ό μˆ˜ν–‰
package com.javaex.lambda;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LambdaEx4 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < 10; i ++) {
            list.add(i);
        }

        //list의 λͺ¨λ“  μš”μ†Œ 좜λ ₯
        list.forEach(i -> System.out.println(i));

        //listμ—μ„œ 2 λ˜λŠ” 3의 배수 제거
        list.removeIf(x -> x%2==0 || x%3==0);   //removeIf(Predicate<E> filter)
        System.out.println(list);

        //list의 각 μš”μ†Œμ— 10을 κ³±ν•œλ‹€.
        list.replaceAll(i -> i*10); //void replaceAll(UnaryOperator<E> operator)
        System.out.println(list);

        Map<String, String> map = new HashMap<>();
        map.put("1", "1");
        map.put("2", "2");
        map.put("3", "3");
        map.put("4", "4");

        //void forEach(BiConsumer<K,V> action)
        map.forEach((k,v) -> System.out.println("["+k+","+v+"]"));
    }
}

그리고 μ•žμ—μ„œ μ„€λͺ…ν•œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” μ˜ˆμ œλ‹€.
μ‰¬μš΄ λ“― ν—·κ°ˆλ €μ„œ 주석을 꼼꼼히 λ‹¬μ•˜λ‹€.

package com.javaex.lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class LambdaEx5 {
    public static void main(String[] args) {
        /*Suplier<T>λŠ” λ§€κ°œλ³€μˆ˜λŠ” μ—†κ³  λ°˜ν™˜κ°’λ§Œ μžˆλŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‹€.
        μΆ”μƒλ©”μ„œλ“œ T get()κ°€ 1 ~ 100 사이 μž„μ˜μ˜ 수λ₯Ό λ¦¬ν„΄ν•˜λ„λ‘ κ΅¬ν˜„ν•œλ‹€.*/
        Supplier<Integer> supplier = () -> (int)(Math.random()*100) + 1;

        /*Consumer<T>λŠ” λ§€κ°œλ³€μˆ˜λ§Œ 있고 λ°˜ν™˜κ°’μ΄ μ—†λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‹€.
        * void accept(T t)λ₯Ό μž…λ ₯ 받은 λ§€κ°œλ³€μˆ˜λ₯Ό 좜λ ₯ν•˜λ„λ‘ κ΅¬ν˜„ν•˜μ˜€λ‹€.
        * */
        Consumer<Integer> consumer = i -> System.out.print(i + ",");

        /*
        * Predicate<T>λŠ” ν•˜λ‚˜μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό μž…λ ₯ λ°›κ³ , boolean을 returnν•˜λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‹€.
        * boolean test(T t)λ₯Ό μž…λ ₯ 받은 tκ°€ 2의 배수(i%2==0)라면 true μ•„λ‹ˆλΌλ©΄ falseλ₯Ό 좜λ ₯ν•˜λ„λ‘ κ΅¬ν˜„ν•˜μ˜€λ‹€.
        * */
        Predicate<Integer> predicate = i -> i%2==0;

        /*
        * Function<T,R>은 ν•˜λ‚˜μ˜ λ§€κ°œλ³€μˆ˜Tλ₯Ό λ°›μ•„ ν•˜λ‚˜μ˜ κ²°κ³ΌRλ₯Ό 좜λ ₯ν•œλ‹€.
        * R apply(T t)λ₯Ό μž…λ ₯ 받은 t의 일의 자리λ₯Ό 없애도둝 κ΅¬ν˜„ν•˜μ˜€λ‹€.
        * */
        Function<Integer, Integer> function = i -> i/10*10; //i의 일의 자리λ₯Ό μ—†μ•€λ‹€.

        List<Integer> list = new ArrayList<>();

        //list에 10개의 λ‚œμˆ˜λ₯Ό μ €μž₯ν•œλ‹€.
        makeRandomList(supplier, list);
        //확인
        System.out.println(list);

        //list에 μ €μž₯된 κ°’ 쀑에, 2의 배수인 κ²ƒλ§Œ 좜λ ₯ν•œλ‹€
        printEvenNum(predicate, consumer, list);

        //list에 μ €μž₯된 κ°’λ“€μ˜ 일의 자리λ₯Ό μ—†μ• μ„œ Listλ₯Ό returnν•˜λŠ” λ©”μ„œλ“œ
        List<Integer> newList = doSomething(function, list);
        System.out.println(newList);

    }

    static <T> List<T> doSomething(Function<T,T> f, List<T> list) {
        List<T> newList = new ArrayList<>();

        /*list에 μ €μž₯된 값을 i에 λŒ€μž…ν•œλ‹€.
        * i에 λŒ€μž…λœ κ°’μ—μ„œ 일의 자리λ₯Ό μ—†μ• κ³ f.apply(i) newList에 μ €μž₯ν•œλ‹€.
        * */
        for (T i : list) { newList.add(f.apply(i)); }

        //list의 값듀을 일의 자리만 μ—†μ•€ μ±„λ‘œ return
        return newList;
    }


    static <T> void printEvenNum(Predicate<T> p, Consumer<T> c, List<T> list) {
        System.out.print("[");

        /*
        * μž…λ ₯ list의 값을 ν•˜λ‚˜μ”© i에 λŒ€μž…ν•œλ‹€.
        * κ·Έ 쀑에 2의 배수인 κ²ƒλ§Œ Consumer<T> c에 λ‹΄λŠ”λ‹€.
        * accept()λŠ” λ§€κ°œλ³€μˆ˜ 인자둜 받은 iλ₯Ό 좜λ ₯ν•œλ‹€.
        * */
        for (T i : list ) {
            if (p.test(i)) {
                c.accept(i);
            }
        }
        System.out.println("]");
    }

    //μž…λ ₯받은 list에 λ‚œμˆ˜ μ—΄ 개λ₯Ό μ €μž₯ν•œλ‹€.
    static <T> void makeRandomList(Supplier<T> s, List<T> list) {
        for (int i=0; i<10; i++) {
            /*
            * λ°˜λ³΅λ¬Έμ„ λŒλ©΄μ„œ
            * s.get()을 ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€
            * 1 ~ 100 사이 μž„μ˜μ˜ 수λ₯Ό 좜λ ₯ν•œλ‹€.
            * */
            list.add(s.get());
        }
    }
}

κΈ°λ³Έν˜•μ„ μ‚¬μš©ν•˜λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

μœ„ 예제λ₯Ό κΈ°λ³Έν˜•μ„ μ‚¬μš©ν•˜λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‘œ λ°”κΎΌ 것이닀.
주석은 μœ„μ— μƒμ„Έν•˜κ²Œ λ‹¬μ•˜μœΌλ―€λ‘œ μƒλž΅ν•œλ‹€.

package com.javaex.lambda;

import java.util.Arrays;
import java.util.function.IntConsumer;
import java.util.function.IntPredicate;
import java.util.function.IntSupplier;
import java.util.function.IntUnaryOperator;

public class LambdaEx6 {
    public static void main(String[] args) {
        IntSupplier s = () -> (int)(Math.random() * 100) + 1;
        IntConsumer c = i -> System.out.print(i + ",");
        IntPredicate p = i -> i%2==0;
        IntUnaryOperator op = i -> i/10*10; //일의 자리 μ—†μ•€λ‹€.

        int[] arr = new int[10];

        makeRandomList(s, arr);
        System.out.println(Arrays.toString(arr));
        printEvenNum(p, c, arr);
        int[] newArr = doSomething(op, arr);
        System.out.println(Arrays.toString(arr));
    }

    static void makeRandomList(IntSupplier s, int[] arr) {
        for (int i = 0; i<arr.length;i++){
            arr[i] = s.getAsInt();  //get이 μ•„λ‹ˆλΌ getAsInt()
        }
    }
    static void printEvenNum (IntPredicate p, IntConsumer c, int[] arr) {
        System.out.print("[");
        for (int i : arr ) {
            if (p.test(i)) {
                c.accept(i);
            }
        } //for
        System.out.print("]");
        System.out.println();
    } // end printEvenNum

    static int[] doSomething(IntUnaryOperator op, int[] arr) {
        int[] newArr = new int[arr.length];

        for (int i = 0; i < newArr.length; i++) {
            newArr[i] = op.applyAsInt(arr[i]);  //apply()μ•„λ‹˜
        }

        return newArr;
    }


}

'Java' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

μ˜ˆμ™Έμ²˜λ¦¬  (0) 2020.09.10
Stream  (0) 2020.09.10
μ œλ„€λ¦­ λ©”μ„œλ“œGeneric Method  (0) 2020.09.09
μ™€μΌλ“œμΉ΄λ“œ  (0) 2020.09.09
μ œλ„€λ¦­ 클래슀Generics Class  (0) 2020.09.09