Java8 특징 정리

Java8 특징

Java 8 provides following features for Java Programming:

  • Lambda expressions *
  • Method references *
  • Functional interfaces *
  • Stream API *
  • Default methods *
  • Static methods in interface *
  • Optional class *
  • Collectors class *
  • ForEach() method *
  • Parallel array sorting *
  • Type and Repating Annotations
  • Nashorn JavaScript Engine
  • Base64 Encode Decode
  • IO Enhancements
  • Concurrency Enhancements
  • JDBC Enhancements etc.

간단하게 정리하고자 한다.

Lambda Expressions

람다식은 함수적인 표현을 쓸 수 있게 도와주는 형식이다. 간결하게 표현가능하며, anonymous function이라고도 할 수 있다.

package hee;

public class LambdaExpressions {

    public static void main(String[] args) {

        int width=10;

        //with lambda
        Drawable d2=()->{
            System.out.println("Drawing "+width);
        };
        d2.draw();
    }
}

@FunctionalInterface  //It is optional
interface Drawable{
    public void draw();
}

Lambda expression helps us to write our code in functional style. It provides a clear and concise way to implement SAM interface(Single Abstract Method) by using an expression. It is very useful in collection library in which it helps to iterate, filter and extract data.

Method References

메소드 레퍼런스는 Reference to a static method. Reference to an instance method. Reference to a constructor.

3개의 경우에 대해 사용할 수 있다. 메소드 레퍼런스는 이미 우리가 구현하고자 하는 람다식 자체가 구현되어있는 경우가 있는데 이럴때 사용하는 메서드 참조용 특수 문법을 메소드 참조 라고 표현한다.

자주쓰는 표현에서는 아래와 같은 게 메소드 레퍼런스이다.

// Component::getValue - instance method 레퍼런스 사용
components.sort(Comparator.comparing(Component::getValue));

Java 8 Method reference is used to refer method of functional interface . It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.

Functional Interface

함수형 인터페이스는 @FunctionalInterface 를 붙이길 권장한다. 여러 개의 abstract, default 메소드가 있는 건 상관없으나 abstract method는 하나여야 한다.

An Interface that contains only one abstract method is known as functional interface. It can have any number of default and static methods. It can also declare methods of object class. Functional interfaces are also known as Single Abstract Method Interfaces (SAM Interfaces).

자주 사용하는 것 중에 function interface가 Comparator 인터페이스가 있다. Comparator을 까보면(?) compare 만 abstract method고 다른 메소드들은 default나 static이다. equal 도 abstract인데 Object class method들은 상관없다고 한다😜

// It can contain any number of Object class methods.  
  int hashCode();  
  String toString();  
  boolean equals(Object obj);

Default Methods

java8이 들어오면서 인터페이스에 변화가 생긴 것 중에 하나이다. default 메소드를 사용해서 구현체를 인터페이스에 만들 수 있다는 사실! default와 static 메소드를 통해 인터페이스에도 구현체를 만들 수 있게 됨으로써 인터페이스를 활용하기 용이해졌다.

public interface FInterface {

    int getInt();
    void printAbstractMethod();

    default void printValue() {
        // do something
    }

    static void printValue2() {
        // do something
    }
}

❗️java8에서 인터페이스와 추상클래스의 차이?

  • 추상클래스와 인터페이스는 인스턴스화 하는 것은 불가능하며, 구현부가 있는 메소드와 없는 메소드 모두 가질 수 있다는 점에서 유사하다.
  • 인터페이스에서 모든 변수는 기본적으로 public static final 이며, 모든 메소드는 public abstract 인 반면 추상클래스에서는 static 이나 final 이 아닌 필드를 지정할 수 있고, public, protected, private 메소드를 가질 수 있다.
  • 인터페이스를 구현하는 어떤 클래스는, 다른 여러개의 인터페이스들을 함께 구현할 수 있다. 추상클래스는 상속을 통해 구현되는데, 자바에서는 다중상속을 지원하지 않으므로 추상클래스를 상속받은 서브클래스는 다른 클래스를 상속받을 수 없다.

출처

Java provides a facility to create default methods inside the interface. Methods which are defined inside the interface and tagged with default keyword are known as default methods. These methods are non-abstract methods and can have method body.

Date/Time API

java8 이전에 Date api가 문제점이 많다고 들었다. immutable 해야하는데 수정할 수 있고 막… 그랬어서 이번에 java8에서 많이 개편됐다고 들음! LocalDate, LocalTime과 같은 api가 추가된 것 같은데 잘 쓰는 중이다.

Java has introduced a new Date and Time API since Java 8. The java.time package contains Java 8 Date and Time classes.

Stream API

Stream은 컬렉션, 배열등의 저장 요소를 하나씩 참조하며 함수형 인터페이스(람다식)를 적용하며 반복적으로 처리할 수 있도록 해주는 기능이다. 스트림은

  • 재사용할 수 없고
  • 지연처리(lazy invocation)되며
  • ParallelStream은 여러 스레드가 작업

    Java 8 java.util.stream package consists of classes, interfaces and an enum to allow functional-style operations on the elements. It performs lazy computation. So, it executes only when it requires.

❗️스트림은 일반적으로 collection과 비교가 되는 것 같다. 뭐가 다를까?

A collection is an in-memory data structure, which holds all the values that the data structure currently has—every element in the collection has to be computed before it can be added to the collection. In contrast, a stream is a conceptually fixed data structure in which elements are computed on demand.

java8 docs Streams differ from collections in several ways:

  • No storage. 스트림은 요소를 저장하는 데이터 구조가 아니다. 소스에서 요소들을 나르는 것이라고 설명하고 있다.

    A stream is not a data structure that stores elements; instead, it conveys elements from a source such as a data structure, an array, a generator function, or an I/O channel, through a pipeline of computational operations.

  • Functional in nature. 태생이 함수형이라는 것이다. 스트림의 오퍼레이션은 결과값을 생성하는 것이지 소스를 수정하는 데에 있지 않다.

    An operation on a stream produces a result, but does not modify its source. For example, filtering a Stream obtained from a collection produces a new Stream without the filtered elements, rather than removing elements from the source collection.

  • Laziness-seeking. 지연처리된다. 스트림 오퍼레이션은 대부분 lazily하게 구현되어 있다. 최종연산을 할 때 중간연산이 같이 된다.

    Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, “find the first String with three consecutive vowels” need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.

  • Possibly unbounded. 가능하면 거의 무한하다(?) 콜렉션은 제한된 사이즈를 가지지만 스트림은 그렇지 않다. short-circuiting 연산을 사용하면 무한한 자원에 대한 연산을 유한한 시간 내에 완료할 수 있다.

    While collections have a finite size, streams need not. Short-circuiting operations such as limit(n) or findFirst() can allow computations on infinite streams to complete in finite time.

  • Consumable. 소모된다. 스트림의 한 사이클동안에 요소는 한번만 방문된다. 소스의 같은 요소에 접근하고 싶으면 새로운 스트림 생성이 필수이다.

    The elements of a stream are only visited once during the life of a stream. Like an Iterator, a new stream must be generated to revisit the same elements of the source.

그 외

그 외에 더 많은 feature들이 많지만 내가 사용하는 정도의 범위에서 정리했다.

참고


Written by@heeye
Work for a financial company as a Backend developer & Cloud engineer😌

GitHub