반응형

전체 글 145

[Effective Java] Item48. 스트림 병렬화는 주의해서 사용하라

병렬화는 신중히 병렬화를 잘 못 사용하면 오히려 성능이 더 나빠질 수 있기 때문에 주의해서 사용해야 합니다. public static void main(String[] args) { primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) .filter(mersenne -> mersenne.isProbablePrime(50)) .limit(20) .forEach(System.out::println); } static Stream primes() { return Stream.iterate(TWO, BigInteger::nextProbablePrime); } 성능을 기대하고 paralle()을 호출하면 아무것도 출력하지 못합니다. 이는 스트림이 파이프라인을 ..

[Effective Java] Item47. 반환 타입으로는 스트림보다 컬렉션이 낫다

스트림 반복 Stream 인터페이스는 Iterable 인터페이스의 추상 메서드를 모두 포함하고 있고, 정의한 방식대로 동작하지만 Iterable 을 확장하지는 않았기 때문에 for-each로 반복할 수 없습니다. 만약 Stream을 반복문으로, 또는 그 반대로 사용하고 싶은 경우에는 중개해주는 어댑터를 사용합니다. Stream -> Iterable public static Iterable iterableOf(Stream stream){ return stream::iterator; } for (ProcessHandle p : iterableOf(ProcessHandle.allProcesses())) { // ... } Iterable -> Stream public static Iterable streamO..

[Effective Java] Item46. 스트림에서는 부작용 없는 함수를 사용하라

Map freq = new HashMap(); try(Stream words = new Scanner(file).tokens()) { words.forEach(word -> { freq.merge(word.toLowerCase(), 1L, Long::sum); }); } forEach 내부에서 외부 상태(freq)를 수정하므로 순수 함수가 아닙니다. Map freq; try(Stream words = new Scanner(file).tokens()) { freq = words.collect(groupingBy(String::toLowerCase, counting())); } Collector collect 메서드는 스트림 종료작업으로 Collector 타입의 인자를 받아서 처리합니다. java.util...

[Effective Java] Item45. 스트림은 주의해서 사용하라

스트림(Stream) API? 스트림 API는 다량의 데이터 처리 작업을 위해 JDK8부터 추가되었습니다. 스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 의미하며, 스트림 파이프라인은 이 원소들로 수행하는 연산단계를 표현하는 개념입니다. 스트림 안의 데이터 원소들은 기본적으로 객체 참조타입이며, int, long, double의 세가지 기본타입을 지원하기도 합니다. 스트림 파이프라인 public static void main(String[] args) { List.of("apple", "banana", "car") // 리스트 .stream() // 소스 스트림 .filter(s -> s.startsWith("b")) // 중간 연산 .forEach(System.out::println); // 종단 연..

[Effective Java] Item 44. 표준 함수형 인터페이스를 사용하라

표준 함수형 인터페이스 java.util.function패키지에는 총 43개의 함수형 인터페이스를 제공합니다. 이 중 6개 정도만 기억하면 나머지도 유추하기 쉽습니다. UnaryOperator T apply(T t): 반환값과 인수의 타입이 같은 함수, 인수는 1개. String::toLowerCase BinaryOperator T apply(T t1, T t2): 반환값과 인수의 타입이 같은 함수, 인수는 2개. BigInteger::add Predicate boolean test(T t): 한 개의 인수를 받아서 boolean을 반환하는 함수. Collection::isEmpty Function R apply(T t): 인수와 반환 타입이 다른 함수. Arrays::asList Supplier T g..

[Effective Java] Item43. 람다보다는 메서드 참조를 사용하라

메서드 참조 List.of(1, 2, 3, 4).forEach(i -> System.out.println(i)); List.of(1, 2, 3, 4).forEach(System.out::println); // 메서드 참조 메서드 참조를 사용할 때 주의사항 대부분의 경우 람다에 비해 코드가 간결하고 명확해지지지만 람다에서 사용하는 매개변수 이름이 좋은 가이드가 된다면 코드가 더 길더라도 오히려 읽기가 더 쉬워질 것입니다. 또한, 메서드의 이름이 너무 길다면 오히려 람다가 더 간결해 질 수 있습니다. service.execute(() -> action()); service.execute(GoshThisClassNameIsHumongous::action); // 메서드 참조 메서드 참조의 유형 정적 메서드 참..

[Effective Java] Item42. 익명 클래스보다는 람다를 사용하라

람다의 장점 람다식은 메서드가 하는 일을 보다 간결하고 읽기 쉽게 표현합니다. 익명 클래스로 작성된 코드입니다. Collection.sort(words, new Comparator() { public int compare(String s1, String s2){ return Integer.compare(s1.length(), s2.length()); } }); 람다식으로 바꾸면 Collection.sort(words, (s1,s2) -> Integer.compare(s1.length(), s2.length())); 열거 타입에서의 람다 public enum Operation { PLUS("+") { public double apply(double x, double y) { return x + y; } }..

[Effective Java] Item41. 정의하려는 것이 타입이면 마커 인터페이스를 활용하라

마커 인터페이스 일반적인 인터페이스와 동일하지만 아무 메서드도 선언하지 않은 형태의 인터페이스입니다. 자신을 구현하는 클래스가 특정 속성을 가짐을 표시하기 위해 사용합니다. 대표적인 마커 인터페이스로는 Serializable, Cloneable 등이 있습니다. 마커 애너테이션과의 비교 마커 인터페이스의 장점 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 사용할 수 있습니다. ObjectOutputSteam.writeObject메서드의 경우 Serializable을 구현하지 않은 경우 NotSerializableException예외를 발생시킵니다. 마커 애너테이션도 Java Reflection을 이용하여 같은 기능을 할 수 있습니다. @MySerializable public clas..

[Effective Java] Item40. @Override 애너테이션을 일관되게 사용하라

@Override @Override 애너테이션은 메서드 선언에만 달 수 있으며, 해당 메서드가 상위 타입의 메서드를 재정의했다는 것을 알려줍니다. 붙이지 않아도 컴파일 오류가 나지 않지만 버그를 예방할 수 있기 때문에 사용하는 것이 좋습니다. @Override를 사용하지 않으면? public class MyClass { private final int a; public MyClass(int a) { this.a = a; } public boolean equals(MyClass m) { return m.a == a; } public int hashCode() { return a; } public static void main(String[] args) { Set set = new HashSet(); for..

[Effective Java] Item39. 명명 패턴보단 어노테이션

명명 패턴 Junit 3까지 테스트 메서드의 이름이 test로 시작해야만 했던 것과 같이 이름을 짓는 규칙 명명 패턴의 문제 오타 올바른 프로그램 요소만 사용되리란 보증이 없음 프로그램 요소를 매개변수로 전달할 마땅한 방법이 없음 어노테이션 jdk 5부터 추가된 기능, 추가적인 정보를 제공하는 메타 데이터 메타 데이터이기 때문에 비즈니스 로직에 직접적인 영향을 주진 않지만, 이 정보에 따라서 실행 흐름을 변경할수 있는 코딩이 가능하여 더 깔끔한 코딩이 가능해 질 수 있음 마커 어노테이션 (Marker annotation) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test {} 메타 어노테이션: 어노테..