Home NhnAcademy 선발교육과정 18일차 (분해와 추상화, Collection framework - lambda)
Post
Cancel

NhnAcademy 선발교육과정 18일차 (분해와 추상화, Collection framework - lambda)

Java 객체지향 프로그래밍

분해(Decomposition)와 추상화(Abstraction)

  • 분해
    • 큰 문제를 해결하기 위한 기본 패러다임: 분할과 정복
    • 간단하고 잘 정의된 방식으로 서로 상호작용하는 작은 프로그램을 만드는 것
    • 다음과 같은 방식으로 분리 가능한 하위 문제로 분해
      • 각 하위 문제는 동일한 세부 수준에 있음
      • 각 하위 문제는 독립적으로 해결할 수 있음
      • 하위 문제에 대한 솔루션을 결합하여 원래 문제를 해결할 수 있음
  • 추상화
    • 고려할 세부 수준을 변경하여 분해를 생산적으로 수행하는 방법
    • 문제를 더 간단한 문제로 변환하기 위해 특정 세부 사항을 무시하는데 동의
    • 프로그램 설계 프로세스의 전형
    • 분해를 위한 구성요소의 좋은 선택

Collection framework에서 함수형 인터페이스를 사용하는 method

interfacemethod설명
Collectionboolean removeIf(Predicate filter)조건에 맞는 요소를 삭제
Listvoid replaceAll(UnaryOperator operator)모든 요소를 변환하여 대체
Iterablevoid forEach(Consumer action)모든 요소에 작업 action 수행
MapV compute(K key,BiFunction<K,V,V>f)지정된 키의 값에 작업 f를 수행
 V computeIfAbsent(K key , Function<K,V> f)키가 없으면 , 작업 f 수행 후추가
 V computeIfPresent(K key , BiFunction<K,V,V>) f지정된 키가 있을 때, 작업 f 수행
 V merge(K key , BiFunction<V,V,V> f)모든 요소에 병합한 f를 수행
 void forEach(BiConsumer<K,V> action)모든 요소에 작업 action을 수행
 void replaceAll(BiFuntion<K,V,V> f)모든 요소에 치환작업 f 를 수행

Map

  • V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface Map<K, V> {
  default V compute(K key,
      BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue = get(key);

    V newValue = remappingFunction.apply(key, oldValue);
    if (newValue == null) {
      // delete mapping
      if (oldValue != null || containsKey(key)) {
        // something to remove
        remove(key);
        return null;
      } else {
        // nothing to do. Leave things as they were.
        return null;
      }
    } else {
      // add or replace old mapping
      put(key, newValue);
      return newValue;
    }
  }
}

K가 Null 이 아니고 Function 값이 0이면 remove 하고 0이 아니라면 새로운 값을 put한다.

  • V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface Map<K, V> {
  default V computeIfAbsent(K key,
      Function<? super K, ? extends V> mappingFunction) {
    Objects.requireNonNull(mappingFunction);
    V v;
    if ((v = get(key)) == null) {
      V newValue;
      if ((newValue = mappingFunction.apply(key)) != null) {
        put(key, newValue);
        return newValue;
      }
    }
    return v;
  }
}

K가 Null 이고 Function 수행 값이 0이 아니면 수행 값을 put 한다.

  • default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface Map<K, V> {
  default V computeIfPresent(K key,
      BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue;
    if ((oldValue = get(key)) != null) {
      V newValue = remappingFunction.apply(key, oldValue);
      if (newValue != null) {
        put(key, newValue);
        return newValue;
      } else {
        remove(key);
        return null;
      }
    } else {
      return null;
    }
  }
}

K가 Null 이 아니고 Function 수행 값이 0이 아니면 수행 값을 put 한다.

  • default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface Map<K, V> {
  default V merge(K key, V value,
      BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    Objects.requireNonNull(value);
    V oldValue = get(key);
    V newValue = (oldValue == null) ? value :
        remappingFunction.apply(oldValue, value);
    if (newValue == null) {
      remove(key);
    } else {
      put(key, newValue);
    }
    return newValue;
  }
}

K가 존재하고 V가 null이 아니면 (oldValue == null) ? value : remappingFunction.apply(oldValue, value); 결과 값을 put한다.

  • default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface Map<K, V> {
  default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
    Objects.requireNonNull(function);
    for (Map.Entry<K, V> entry : entrySet()) {
      K k;
      V v;
      try {
        k = entry.getKey();
        v = entry.getValue();
      } catch (IllegalStateException ise) {
        // this usually means the entry is no longer in the map.
        throw new ConcurrentModificationException(ise);
      }
      // ise thrown from function is not a cme.
      v = function.apply(k, v);
      try {
        entry.setValue(v);
      } catch (IllegalStateException ise) {
        // this usually means the entry is no longer in the map.
        throw new ConcurrentModificationException(ise);
      }
    }
  }
}

존재하는 모든 K의 V를 Function 의 수행 값을 setValue 한다.

Function을 확장

  • UnaryOperator : extends Function <T,T>
1
2
3
4
5
6
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
    static <T> UnaryOperator<T> identity() {
        return t -> t;
    }
}

Type T의 인자 하나를 받고, 동일한 Type T 를 반환하는 인터페이스

  • BinaryOperator : extends BiFunction <T,T,T>
1
2
3
4
5
6
7
8
9
10
11
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
    public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
    }
    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }
}

Type T의 인자 두개를 받고, 동일한 Type T 를 반환하는 인터페이스

Stream

  • 스트림은 데이터 소스를 변경하지 않으며 일회용 작업입니다.
  • 람다식으로 요소를 처리 함으로써 코드가 간결해지는 장점이 있습니다.
  • 내부 반복자를 사용하여 병렬처리가 쉽습니다.

c

This post is licensed under CC BY 4.0 by the author.