JiwonDev

#10 Modern Java (Java8~)

by JiwonDev

# ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค(๋žŒ๋‹ค)

ํด๋ž˜์Šค๋ฅผ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ๋”ฑ ํ•˜๋‚˜๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค
  • SAM (Single Abstract Method, ๋‹จ ํ•˜๋‚˜์˜ ์ถ”์ƒ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ) ์ธํ„ฐํŽ˜์ด์Šค
  • @FuncationInterface ์• ๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค ( ์—†๋”๋ผ๋„ ์œ„ 2์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด ๋™์ผ ์ทจ๊ธ‰.)
public class Main {
    public static void main(String[] args) {
    // ์ต๋ช…ํ•จ์ˆ˜ ๋Œ€์‹  ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ ‡๊ฒŒ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
        Hello hello = () -> System.out.println("Hello");
        hello.doSomething(); // Hello ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ž„์„ ์œ ์˜ํ•˜์ž.
    }
}

 


# ๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค

ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์ง€์•Š๊ณ , ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์‰ฝ๊ฒŒ ๋„์™€์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

JS์—์„œ ๊ฐ๊ฐ์˜ ์ž…๋ ฅ ๊ฐ’์— ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์ ์šฉ์‹œ์ผœ์ฃผ๋Š” ๋ฌธ๋ฒ•(Array.map)๊ณผ ๋น„์Šทํ•˜๋‹ค.

์ข…๋ฅ˜ ์‚ฌ์šฉ๋ฐฉ๋ฒ• ์˜ˆ์ œ
Static ๋ฉ”์„œ๋“œ ContainingClass :: staticMethodName Person::compareByAge
ํŠน์ • ๊ฐ์ฒด(myObject)์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ containingObject::instanceMethodName myApp::appendStrings2
ํƒ€์ž… ๊ฐ์ฒด(Type)์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ ContainingType::methodName String::compareToIgnoreCase
String::concat
์ƒ์„ฑ์ž ClassName::new HashSet::new

์ฝ”๋“œ ์˜ˆ์ œ

๋”๋ณด๊ธฐ

Static Method ๋ ˆํผ๋Ÿฐ์Šค ์‚ฌ์šฉ

// ๋‚ด๊ฐ€ ๊ตฌํ˜„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค
interface Executable {
    void doSomething(String text);
}

// ์ด๋ฏธ ์กด์žฌํ•˜๋Š” Static ๋ฉ”์„œ๋“œ
public static class Printer {
    static void printSomething(String text) {
        System.out.println(text);
    }
}

// ๊ผญ ๋žŒ๋‹ค๋กœ ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์ง€ ์•Š๋”๋ผ๋„, ๊ธฐ์กด์— ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.
public static void main(String args[]) {
    // Executable exe = text -> Printer.printSomething(text); ์™€ ๋™์ผํ•œ ์ฝ”๋“œ
    Executable exe2 = Printer::printSomething;
    
    exe2.doSomething("do something");
    
    // ํ•จ์ˆ˜ํ˜• API๋ฅผ ์ด์šฉํ•˜๋ฉด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    Consumer<String> consumer = Printer::printSomething;
    consumer.accept("do something");
}


Instance Method ๋ ˆํผ๋Ÿฐ์Šค ์‚ฌ์šฉ

// ๋‚ด๊ฐ€ ๋งŒ๋“  ์ž„์˜์˜ ํด๋ž˜์Šค.
public static class Company {
    String name;
    public Company(String name) {
        this.name = name;
    }
    
	// static์ด ์•„๋‹Œ ๋ฉ”์„œ๋“œ.
    public void printName() {
        System.out.println(name);
    }
}

public static void main(String args[]) {
    List<Company> companies = Arrays.asList(new Company("google"),
        new Company("apple"), new Company("samsung"));
        
    //companies.stream().forEach(company -> company.printName());์™€ ๋™์ผํ•œ ์ฝ”๋“œ
    companies1.stream().forEach(Company::printName);
    
    
    // ์ด๋Ÿฐ์‹์œผ๋กœ ์‘์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.
    List<String> myCompanies = Arrays.asList("google", "apple", "google", "apple", "samsung");

    myCompanies.stream()
         .mapToInt(String::length) // ๋žŒ๋‹ค์‹: company -> company.length()
         .forEach(System.out::println);
}

 

Constructor Method (new, ์ƒ์„ฑ์ž ๋ ˆํผ๋Ÿฐ์Šค) ์‚ฌ์šฉ

public static class Company {
    String name;
    public Company(String name) {
        this.name = name;
    }

    public void printName() {
        System.out.println(name);
    }
}

public static void main(String args[]) {
    List<String> companies = Arrays.asList("google", "apple", "google", "apple", "samsung");

//  companies.stream() ์ด ์ฝ”๋“œ์™€ ๋™์ผํ•จ.
//      .map(name -> new Company(name))
//      .forEach(company -> company.printName());
    companies.stream()
        .map(Company::new)
        .forEach(Company::printName);
}

 


# ํ•จ์ˆ˜ํ˜• API

์ž๋ฐ”์—์„œ๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด์•ˆ์— ์กด์žฌํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฉ”์„œ๋“œ๋งŒ ๋ฝ‘์•„์„œ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ค์šด๋ฐ, ์ด๋ฅผ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ API ํ‹€์„ ์ œ๊ณตํ•ด์ค€๋‹ค.

// B์‹คํ–‰ ํ›„ ๋ฐ˜ํ™˜๊ฐ’ ์ „๋‹ฌ, ์ดํ›„ A์‹คํ–‰ ์ฆ‰ ํ•จ์ˆ˜์˜ ํ•ฉ์„ฑ์ด๋‹ค.
newFunc = funcA.compose(funcB)
 
// A์‹คํ–‰ ํ›„ B์‹คํ–‰. ๊ทธ๋ƒฅ ๋‹จ์ˆœํžˆ ์—ฐ๋‹ฌ์•„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ ๋ฟ์ด๋‹ค.
newFunc = fucnA.andThen(funcB)
์ข…๋ฅ˜ ํŠน์ง• ํ•จ์ˆ˜ ์กฐํ•ฉ์šฉ ๋ฉ”์„œ๋“œ
Runnable ์ธ์ž์™€ ๋ฐ˜ํ™˜๊ฐ’์ด ๋ชจ๋‘ ์—†์Œ. ๋‹จ์ง€ ์‹คํ–‰๋งŒ ๊ฐ€๋Šฅ  
Function<T,R> ์ธ์ž1๊ฐœ, ๋ฐ˜ํ™˜1๊ฐœ R apply(T t) andThen, Compose
BiFunction<T,U,R> ์ธ์ž2๊ฐœ, ๋ฐ˜ํ™˜1๊ฐœ R apply(T t, U u)  
Consumer<T> ์ธ์ž๋งŒ ์žˆ์Œ. void accept(T t) andThen
Supplier<T> ๋ฐ˜ํ™˜๊ฐ’๋งŒ ์žˆ์Œ. T get()  
Predicate<T> ๋ฐ˜ํ™˜๊ฐ’๋งŒ ์žˆ์Œ. boolean test(T t) And, Or, Negate
UnaryOperator<T> Function<T, T> ์™€ ๋™์ผ, ์ธ์ž์™€ ๊ฐ™์€ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•จ  
BinaryOperator<T> BiFunction<T, T, T> ์™€ ๋™์ผ, ์ž…๋ ฅ๊ฐ’ ๋‘๊ฐœ๋ฅผ ๋ฐ›์•„ ๋™์ผํ•œ ํƒ€์ž…์„ ๋ฆฌํ„ดํ•จ.  
Comparator<T> BiFunction<T,T,Integer> ์™€ ๋™์ผ, ๊ฐ์ฒด๊ฐ„์˜ ๊ฐ’ ๋น„๊ตํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋จ (compare)  
๊ธฐํƒ€ ์ƒ๋žต BiCosumer<T,U> BiPredicate<T,U>, ObjIntConsumer, LongSupplier ๋“ฑ.  
import java.util.function.DoubleFunction;
import java.util.function.Function;
 
public class Main {
    public static void main(String[] args) {
        // ์ด๋ ‡๊ฒŒ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ  apply ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
        Function<String, Integer> toStr = str -> Integer.parseInt(str);
        Integer result = toStr.apply("10");
 
        // ์ž…๋ ฅ๊ฐ’์ด ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด DoubleFunction, IntFunction ๋“ฑ์„ ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.
        DoubleFunction<Integer> func = a -> (int) (a * 10);
        System.out.println(func.apply(3.2)); // 32
 
        // ์ด๋Š” ์œ„์— ์ฝ”๋“œ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
        Function<Integer,Integer> multiply10 = a -> (int) (a * 10);
 
        // ์ด๋Ÿฐ์‹์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ํ•ฉ์„ฑํ•ด์„œ ์‚ฌ์šฉ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
        Function<String,Integer> toStringAndMultiply10 = multiply10.compose(toStr);
        System.out.println(toStringAndMultiply10.apply("10")); // 100
    }
}

 


# ์ƒˆ๋กœ์šด ์ดํ„ฐ๋ ˆ์ดํ„ฐ (forEach, spliteraor)

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐœ๋…์ด ๋“ฑ์žฅํ•˜๋ฉด์„œ, ์ด๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•ด ์ƒˆ๋กœ์šด ํ˜•ํƒœ์˜ iterator๋„ ๋ช‡๊ฐ€์ง€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

์—ฌ๋‹ด์œผ๋กœ ๋ชจ-๋˜ํ•œ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ๋ฌด์กฐ๊ฑด ์ข‹์€ ๊ฑด ์•„๋‹ˆ๋‹ค. ๋ญ๋“ ์ง€ ์žฅ๋‹จ์ ์€ ์žˆ์œผ๋ฏ€๋กœ ํ•„์š”ํ•  ๋•Œ ์ ์ ˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

List<Integer> list = Arrays.asList(1, 2, 3);
 
// ๊ธฐ์กด์˜ forEach๋ฌธ
for (Integer i : list)
    System.out.println(i);

for (Integer i : list)
    for (int j = 0; j < i; j++)
        System.out.println(i * j);

// ์ƒˆ๋กœ์šด forEach ๋ฉ”์„œ๋“œ. ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์ฃผ๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
list.forEach(System.out::println);

// ์ด ์ •๋„๋กœ ๋‹จ์ˆœํ•œ ์ž‘์—…์€ ํ•จ์ˆ˜ํ˜•์„ ์“ฐ์ง€์•Š๋Š” ๊ฒƒ์ด ๋” ์ข‹์„ ์ˆ˜๋„ ์žˆ๋‹ค.
list.forEach(i -> {
    IntStream.range(0, i).forEach(j -> {
        System.out.println(i * j);
    });
});

 

Split + erator๋Š” ์ด๋ฆ„์—์„œ๋„ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ์ž‘์—…์„ ์—ฌ๋Ÿฌ๊ฐœ๋กœ ์ชผ๊ฐค ์ˆ˜ ์žˆ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.

Stream์ด ์ƒ๊ธฐ๋ฉด์„œ Stream์„ ์—ฌ๋Ÿฌ๊ฐœ๋กœ ์ชผ๊ฐœ ํŒŒ์ดํ”„๋ผ์ด๋‹์„ ์‰ฝ๊ฒŒํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ๋ฉ”์„œ๋“œ์ด๋‹ค.

 

Spliterator์˜ ์†Œ๊ฐœ ๋ฐ ํ™œ์šฉ (in JDK 1.8)

JDK 1.8 ์—์„œ ์ถ”๊ฐ€๋œ Stream API ์ค‘ Spliterator ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ•™์Šตํ•œ ๋‚ด์šฉ์— ๋Œ€ํ•ด ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

jistol.github.io

// Stream๊ณผ Collection์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ spliterator ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.     
Spliterator<Integer> byStream = IntStream.range(0, 100).spliterator();    
Spliterator<Integer> byCollection = (new ArrayList<Integer>()).spliterator();    

// ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ Spliterators ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด Spliterator ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Spliterator<Integer> byArray = Spliterators.spliterator(new int[]{1,2,3,4}, Spliterator.SORTED);
public void trySplit_test() {
    // ์ด๋ ‡๊ฒŒ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ถ„ํ• ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    Spliterator<Integer> origin = IntStream.range(0, 19).spliterator();
    Spliterator<Integer> dest = origin.trySplit();

    System.out.println(dest.estimateSize());  // ํฌ๊ธฐ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ size is 9
    dest.forEachRemaining(System.out::print); // ๋ถ„ํ• ๋œ iter ์ˆœํšŒ print 0~8
    
    System.out.println(origin.estimateSize());  // size is 10
    origin.forEachRemaining(System.out::print);  // print 9 ~ 18
}

# Stream

Sequence of elements supporting sequential and parallel aggregate operations
(์‹œํ€ธ์Šค ์š”์†Œ ๋ฐ ๋ณ‘๋ ฌ ์ž‘์—…์„ ๋„์™€์ฃผ๋Š” ์—ฐ์‚ฐ)

์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ์ปฌ๋ ‰์…˜์ด ์•„๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ (=์›๋ณธ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ) ํ•จ์ˆ˜ํ˜•์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” API์ด๋‹ค. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋ฐฐ์› ๋‹ค๋ฉด, ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ ๋น„์Šทํ•œ ๊ธฐ๋Šฅ์„ ํ•œ๋ฒˆ์ฏค ๋ดค์„ ๊ฒƒ์ด๋‹ค.

  • ์ˆœ์ˆ˜ํ•จ์ˆ˜, Immutable, ์ŠคํŠธ๋ฆผ์ด ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ์ŠคํŠธ๋ฆผ์€ ์žฌ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ์˜ค์ง ํ•œ๋ฒˆ๋งŒ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ์ค‘๊ฐœ ์˜คํผ๋ ˆ์ด์…˜์€ ๊ทผ๋ณธ์ ์œผ๋กœ lazy ํ•˜๋‹ค.
  • lazy ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ ๊ฐ’์ด ๋ฌดํ•œ์ด์—ฌ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. (Short Circuit ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํฌ๊ธฐ๋ฅผ ์ œํ•œ)
  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์†์‰ฝ๊ฒŒ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
List<String> lang = 
  Arrays.asList("Java", "Scala", "Groovy", "Python", "Go", "Swift");

lang.stream() // 1. ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•œ๋‹ค
  .sorted() // 2. ์ค‘๊ฐœ ์—ฐ์‚ฐ
  .collect(Collectors.toList()); // 3. ์ข…๋ฃŒ ์—ฐ์‚ฐ
// [Go, Groovy, Java, Python, Scala, Swift]

lang.stream()
  .sorted(Comparator.reverseOrder())
  .collect(Collectors.toList());
// [Swift, Scala, Python, Java, Groovy, Go]

// ์ŠคํŠธ๋ฆผ์€ ์›๋ณธ ๊ฐ’์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰ ๊ธฐ์กด ๋ฐฐ์—ด lang์˜ ๊ฐ’์€ ๋ณ€ํ•˜์ง€ ์•Š์Œ์„ ๊ธฐ์–ตํ•˜์ž. 
// lang == ["Java", "Scala", "Groovy", "Python", "Go", "Swift"]

์ŠคํŠธ๋ฆผ์—๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ค‘๊ฐœ ์—ฐ์‚ฐ(intermediate operation)๊ณผ ํ•˜๋‚˜์˜ ์ข…๋ฃŒ ์—ฐ์‚ฐ(terminal operation)์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

์ค‘๊ฐœ ์—ฐ์‚ฐ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ข…๋ฃŒ ์—ฐ์‚ฐ์ด ์˜ค๊ธฐ ์ „๊นŒ์ง€ ์‹คํ–‰์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰ lazyํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋ฉฐ ์ž‘์—… ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ค‘๊ฐœ ์—ฐ์‚ฐ์˜ ๋™์ž‘ ์ˆœ์„œ๋Š” ๋ฐ”๋€” ์ˆ˜ ์žˆ๋‹ค.

 

  • ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ
    • 0 ๋˜๋Š” ๋‹ค์ˆ˜์˜ ์ค‘๊ฐœ ์˜คํผ๋ ˆ์ด์…˜ (intermediate operation)๊ณผ ํ•œ๊ฐœ์˜ ์ข…๋ฃŒ ์˜คํผ๋ ˆ์ด์…˜
      (terminal operation)์œผ๋กœ ๊ตฌ์„ฑํ•œ๋‹ค.
    • ์ŠคํŠธ๋ฆผ์˜ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” ์˜ค์ง ํ„ฐ๋ฏธ๋„ ์˜คํผ๋„ค์ด์…˜์„ ์‹คํ–‰ํ•  ๋•Œ์—๋งŒ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ์ค‘๊ฐœ ์˜คํผ๋ ˆ์ด์…˜
    • ์ค‘๊ฐœ ์—ฐ์‚ฐ์€ Stream์„ ๋ฆฌํ„ดํ•œ๋‹ค.
    • Stateless / Stateful ์˜คํผ๋ ˆ์ด์…˜์œผ๋กœ ๋” ์ƒ์„ธํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
      (๋Œ€๋ถ€๋ถ„์€ Stateless์ง€๋งŒ distinct๋‚˜ sorted ์ฒ˜๋Ÿผ ์ด์ „ ์ด์ „ ์†Œ์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•ด์•ผ ํ•˜๋Š” ์˜คํผ๋ ˆ์ด์…˜์€ Stateful ์˜คํผ๋ ˆ์ด์…˜์ด๋‹ค.)
    • filter, map, limit, skip, sorted, ...
  • ์ข…๋ฃŒ ์˜คํผ๋ ˆ์ด์…˜
    • Stream์„ ๋ฆฌํ„ดํ•˜์ง€ ์•Š๋Š”๋‹ค.
    • collect, allMatch, count, forEach, min, max, ...

์ŠคํŠธ๋ง API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ตฌํ˜„ํ•˜๊ฒŒ๋˜๋ฉด, ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ๋†’์•„์ง€๊ณ  ์›๋ณธ์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š์œผ๋ฉฐ ํ•จ์ˆ˜ ์‹คํ–‰์— ์žˆ์–ด Side-effect๋ฅผ ์—†์•  ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.

// ๊ธฐ์กด ์ฝ”๋“œ
final List<Integer> NUMBERS = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer result = null;
for (final Integer number : NUMBERS) {
  if (number > 3 && number < 9) {
    final Integer newNumber = number * 2;
    if (newNumber > 10) {
      result = newNumber;
      break;
    }
  }
}
System.out.println("Imperative Result: " + result);
// Stream ์‚ฌ์šฉ
final List<Integer> NUMBERS = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println("Functional Result: " +
                   NUMBERS.stream()
                   .filter(number -> number > 3)
                   .filter(number -> number < 9)
                   .map(number -> number * 2)
                   .filter(number -> number > 10)
                   .findFirst()
                  );

# Stream API

2021.07.12 - [Backend/Java] - #11 Stream API

 

#11 Stream API

์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ 1. Stream ์ƒ์„ฑ 2. ์ค‘๊ฐœ์—ฐ์‚ฐ 3. ์ตœ์ข…์—ฐ์‚ฐ(Terminal Op) ์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค. # Stream API ํŠน์ง• Java์˜ ๋ชจ๋“  Collection์€ ๋‚ด๋ถ€์— stream()์ด๋ผ๋Š” ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค. ์ปฌ..

jiwondev.tistory.com


# Optional API (null๊ฐ’ ์ฒ˜๋ฆฌ)

2021.07.12 - [Backend/Java] - #12. Optional API (*Null๊ฐ’ ์ฒ˜๋ฆฌ)


 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ