Iterator 그리고 Iterable에 대해 정리

JAVA/고급 자바|2018. 10. 4. 00:19

Java8의 Stream에 map 기능을 사용하다가 이런문제를 겪었다.



Iterable과 Iterator 정확한 정리를 하지 않고 무턱대고 사용하다보니 발생한 문제였다.

정확하게 집고 넘어가기 위해 정리해보자.

Iterator

Iterator는 자바 1.2에 발표된 인터페이스이다.  hasNext, next 등을 통해 현재 위치를 알 수 있고 다음 element가 있는지를 판단하는 기능등에 대한 명세를 제공한다. 이를 사용하기 위해서는 Iterator 인터페이스의 내용을 직접 구현해야 한다. 

대게 Collection 인터페이스를 사용하는 클래스의 경우 별도의 Iterator를 구현하여 사용하고 있다. 밑에 Iterable을 설명하면서 정리해보자.

1
2
3
4
5
6
7
8
9
10
11
12
public interface Iterator<E> {
    boolean hasNext();
    E next();
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    default void forEachRemaining(Consumer<super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}
cs


Iterable

Java 1.5부터 나온 인터페이스로 Iterator보다 더 늦게 나온 인터페이스로 Iterator를 제공하는 메서드를 보유하고 있는 인터페이스이다.

이 인터페이스는 실질적으로 for-each를 사용할 수 있는 클래스라는것을 명세해주는 기능을 제공하고, Iterable을 상속받은 클래스는 Iterator를 사용하여 for- each 기능을 사용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface Iterable<T> {
   Iterator<T> iterator();
    
   default void forEach(Consumer<super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
 
   default Spliterator<T> spliterator() {
       return Spliterators.spliteratorUnknownSize(iterator(), 0);
   }
}
cs

조금 더 이해가 가능하도록 ArrayList를 예로 들어보자.

ArrayList는 List를 구현하고 있고, List는 Collection을 상속받고 있으며 Collection은 Iterable을 상속받고 있다.

1
2
3
4
5
6
7
// ArrayList
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
// List
public interface List<E> extends Collection<E> {
// Collection
public interface Collection<E> extends Iterable<E> {
cs


그래서 ArrayList에 보면 Iterator<E> iterator()가 구현되어 있다.

그리고 Iterator()에서 반환하는 Iterator인터페이스를 구현한 Itr 클래스도 제공하고 있으며 이를 사용하여 반복 동작을 가능하도록 사용한다.

※Java 1.8 부터는 Iterable에 forEach default method를 제공하고 있어서 바로 사용할 수 있다.


결론은
for-each 기능을 제공하는 Collection의 경우 Iterable을 구현하고 있으며, 그 Iterable 인터페이스에 있는 Iterator<E> iterator() 메소드를 구현하여 Collection의 요소들은 Iterate 하는데 사용된다.


댓글()

기타 자바8에 추가된 편리기능

JAVA/Java 8|2018. 5. 31. 07:51

String.joiner
구분자를 이용해서 입력된 데이터를 구분해서 String으로 반환



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Java8Test {
 
    public static void main(String args[]) {
        StringJoiner sj = new StringJoiner(",");
        sj.add("babo");
        sj.add("wedul");
        sj.add("pnp");
        System.out.println(sj.toString());
        
        // 2, 3번재 매개변수를 이용하여 prifix, suffix를 붙힐 수 있다.
        sj = new StringJoiner(",""자기소개 -- "" -- 끝");
        sj.add("babo");
        sj.add("wedul");
        sj.add("pnp");
        System.out.println(sj.toString());
    }
}
 
=> 결과
babo,wedul,pnp
자기소개 -- babo,wedul,pnp -- 끝
cs



String.join
- 구분자를 이용해서 입력된 데이터를 구분해서 String으로 변환

1
2
3
4
5
List<String> data = Arrays.asList("babo", "wedul");
System.out.println(String.join(",", data));
 
==> 결과 
babo,wedul
cs





Collection에서 조건이 부함되면 삭제하는 Removeif

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String args[]) {
    List<String> data = Arrays.asList("babo""wedul");
        
    Predicate<String> predicate = new Predicate<String>() {
        @Override
        public boolean test(String name) {
            return name.equals("wedul");
        }
    };
        
    data.removeIf(predicate);
    data.stream().forEach(System.out::println);
cs


List 포함된 부분중 모든 부분을 한번에 변경할  있는 기능을 제공하는 ReplaceAll


1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String args[]) {
    List<String> data = Arrays.asList("babo""wedul");
        
    // UnaryOperator는 입력된 input의 값을 반화해주는 클래스 함수형 인터페이스
    UnaryOperator<String> unaryOpt = (String name) -> {return "bb wedul";};
        
    data.replaceAll(unaryOpt);
    data.forEach(System.out::println);
 
==> 결과값
bb wedul
bb wedul
cs



List안에 컨텐츠를 comparator 맞게 정렬 시켜주는 sort 메소드




Stream  체크   제거



1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String args[]) {
    List<String> data = Arrays.asList("babo"null"wedul"null);
        
    // null이 있는 부분이 있는지 체크
    System.out.println("is Contain null? : " + data.stream().anyMatch(Objects::isNull));
 
    // 널 제거
    data.stream().filter(Objects::nonNull).forEach(System.out::println);
 
==> 결과
is Contain null? : true
babo
wedul
cs


댓글()

Java8 람다식의 지연실행 (Lazy Programming)

JAVA/Java 8|2018. 5. 31. 07:48

지연실행
-> 람다를 이용하면 필요할때만 호출해서 사용할  있는 Lazy Programming 구현   있다.

기존에 다음과 같이 사용하면 
당장 사용하지 않아도 실행이 되는 문제가 있었다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Heavy {
        Heavy() {
            System.out.println("Heavy created");
        }
    }
    
    Hodler 클래스
    Holder 클래스는 heavy 클래스를 포함하고 있다.
    public class Holder {
        public Holder() {
            System.out.println("Holder created");
        }
    
        Heavy heavy = new Heavy();
        public Heavy getHeavy() {
            return heavy;
        }
    }
    
    public static void main(String[] args) {
        Holder holder = new Holder();
        System.out.println("Get Heavy instance");
    }
cs



Holder 클래스를 선언   다음과 같은 순서로 실행된다.

==> 출력겨로가
Heavy created
Holder created
Get Heavy instance

Heavy 클래스를 가지고 있지만 당장 사용하지 않는데 Holder클래스가 생성될  먼저 생성되는 문제가 있다.
 
이런 문제를 람다식을 사용하여 필요할  호출하여 사용하는 Lazy 방식으로 변경   있다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Lazy<T> {
        private Optional<T> instance = Optional.empty();
        private Supplier<T> supplier;
        
        public Lazy(Supplier<T> theSupplier) {
            supplier = theSupplier;
        }
        
        public T get() {
            if(!instance.isPresent()) {
                instance = Optional.of(supplier.get());
            } 
            
            return instance.get();
        }
    }
cs



먼저 하나의 Lazy방식에 사용할 클래스를 선언한다.
그리고 Holder 클래스를 다음과 같이 변경한다.



1
2
3
4
5
6
7
8
9
10
public class Holder {
        public Holder() {
            System.out.println("Holder created");
        }
    
        Lazy<Heavy> heavy = new Lazy<Heavy> (() -> new Heavy());
        public Heavy getHeavy() {
            return heavy.get();
        }
}
cs



다시한번 실행해 보면

Heavy 클래스가 미리 생성되지 않는것을 확인 할 수 있다.


1
2
3
4
public static void main(String[] args) {
        Holder holder = new Holder();
        System.out.println("Get Heavy instance");
}
cs


댓글()

자바 8에서 java.util.function 패키지에 추가된 기본 함수형 인터페이스 정리

JAVA/Java 8|2018. 5. 31. 07:45

자바 8에서 java.util.function 패키지에 추가된 기본 함수형 인터페이스 정리

Function <T, R> 
=> T 입력으로 R 출력하여 반환



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Java8Test {
 
    public static void main(String args[]) {
        
        Function<String, Integer> mapStrToInt = new Function<String, Integer>() {
            public Integer apply(String str) {
                if (str == "wedul") {
                    return 1;
                }
                return 2;
            }
        };
        
        List<String> testData = Arrays.asList("wedul","dd","babo");
        testData.stream().map(mapStrToInt).forEach(System.out::println);
    }
}
cs




Predicate<T> 
-> T 입력으로 boolean 출력으로 반환


1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String args[]) {
        
    Predicate<Integer> predictData = new Predicate<Integer> () {
        @Override
        public boolean test(Integer tes) {
            return tes > 10
        }
    };
        
    List<Integer> test = Arrays.asList(12,3,4,55);
        
    test.stream().filter(predictData).forEach(System.out::println);
}
cs



Consumer <T>  
-> T 입력으로 아무것도 반환하지 않는다
-> 단순하게 입력받은 데이터를 처리할때 사용된다.



1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String args[]) {
        
    Consumer<Integer> consumerData  = new Consumer<Integer>() {
        @Override
        public void accept(Integer idnt) {
            System.out.println(idnt);
        }
    };
        
    List<Integer> test = Arrays.asList(12,3,4,55);
        
    test.stream().forEach(consumerData);
}
cs




Supplier<T> : 입력을 취하지 않고 T 반환
입력한 데이터를 가지고 있으며get 메소드를 사용하여 호출한 곳에서 입력된 데이터를 사용할  있게 반환  주는 기능 제공



1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String args[]) {
        
    Supplier<Integer> supplier = new Supplier<Integer>() {
        @Override 
        public Integer get() {
            return 1;
        }
    };
        
//        List<Integer> test = Arrays.asList(12,3,4,55);
    System.out.println(supplier.get());
}
cs


댓글()

Java8 스트림을 이용한 데이터 추출

JAVA/Java 8|2018. 5. 31. 07:43

스트림에 있는  데이터를 List, String, Set 다양한 형태로 변경하여 추출   있다.

toArray
Stream.toArray Object[] 리턴한다.
 
올바른 타입의 배열을 원하는 경우 다음과 같이 배열 생성자를 전달한다.
String[] result = words.toArray(String[]::new);
 
Collect 메소드
- Collect : 종료 작업으로 인자로 받은 형태의 데이터 타입으로 결과물을 생성한다
- Collect 병렬화를 지원한다또한 공급자누산자결합자를 기본적인 파라미터로 받으며 이는 
  Collectors라는 클래스를 통해 간편하게 정의하여 사용할  있다.

1) List, set, String



1
2
3
4
5
6
7
Stream<String> data = Stream.of("dd", "aa", "cc");
        
// stream 데이터를 list로 변환
List<String> result = data.collect(Collectors.toList());
        
// stream 데이터를 set으로 추출
Set<String> setdata = data.collect(Collectors.toSet()); 
cs




스트림에 있는 모든 문자열들을 서로 연결해서 모으려고 하는 경우 다음과 같이 호출   있다.
 

문자 이어 붙히기


1
2
3
4
5
6
7
Stream<String> data = Stream.of("dd", "aa", "cc");
        
// 데이터 이어 붙히기
String temp = data.collect(Collectors.joining());
System.out.println(temp);
        
==> ddaacc 
cs




구분자 삽입하여 이어 붙히기

1
2
3
4
5
6
7
8
9
10
public static void main(String args[]) {
        
    Stream<String> data = Stream.of("dd""aa""cc");
        
    // 데이터 이어 붙히기
    String temp = data.collect(Collectors.joining("||"));
    System.out.println(temp);    
}
 
==> dd||aa||Cc
cs


그룹핑과 파티셔닝
그룹핑

 
Stream 들어있는 데이터 중에 성질이 같은 값들의 그룹을 만들어서 사용하고자  경우가 있을 것이다.
Stream collect 메소드의 구분자로 Collectors.groupingby 사용하며 기준은 Person dept 사용하여 그룹핑을 한다.




 다운스트림 컬렉터(downStream Collector)
 -> 그룹핑 결과를 List 반환하지 않고 특별히 기재한 방식으로 출력하도록 해주는 


1) set으로 출력




2) 분류된 데이터의 개수를 출력






파티셔닝
리턴되는 값이 boolean 분류 함수인 경우에는 groupingBy 대신 partitioningBy 사용하면 스트림 요소가 true, false 리턴하는 두개의 리스트로 구분된다.




댓글()

Java8 스트림(stream) 연산

JAVA/Java 8|2018. 5. 31. 07:37

리덕션 연산
Stream reduce 메소드는 2개의 인자를 받아 인자와 같은 값을 리턴하는 (T,T) -> T 메소드이다.
 
 번째 인자는 누적되는 값이 되고, str2 foreach처럼 순서대로 요소가 들어오는 방식이다.



public static void main(String args[]) { List<String> list = Arrays.asList(new String[] {"a", "b", "c"}); Stream<String> stream = list.stream(); Optional<String> opt = stream.reduce((str1, str2) -> str1 + str2); opt.ifPresent(System.out::println); } =>> 리턴 값 "abc"



 다른 형태의 reduce 메소드 
위에서 소개한 reduce 메소드 형태와 다르게 이번에 소개할 Reduce메소드는 3개의 인자를 받는다.
 
 메소드는 반환 받으려는 
타입과 연산하려는 타입이 다를 경우에 사용한다.
 
 reduce 형식은 reduce(U, 함수1, 함수2) 유형이고C
리턴 타입은  번째 인자인 U 타입을 리턴한다.
 
 번째 인자는 시작 값으로 사용된다.
 번째 인자인 함수 1 (U, T) -> U 형식이다인자 2개를 받아  번째 인자의 타입으로 리턴한다.
 번째 인자인 함수2 함수 1 연산 결과들을 모아 연산한다타입은 (U, U) -> U이다.
 
예를 들어서,
WedulObject이라는 객체의 나이를 모두 더해서 값을 출력하고 싶을  사용한다.





1
2
3
4
List<WedulObject> objects = Arrays.asList(new WedulObject("kim"1"dev"), new WedulObject("jun"2"insa"), new WedulObject("jung"3"kakao"));
int ageSum = objects.stream().reduce(0, (result, object) -> result + object.getAge(), (result, age) -> result + age); 
        
System.out.println(ageSum);
cs




 번째 인자에서는  번째 인자인 시작값과 입력된 person age값을 더한다
0 + 10 + 11 + 12
 
 번째 인자에서는  번째 인자에서 나온 결과를 모두 더한다.
10 + 11 + 12 = 33
※여기서 시작값을 1 바꾸면 결과는 34, 2 바꾸면 35 출력된다.
 
이러한 방식을 사용하는 이유는 
입력된 person age값을  번째 인자에서 병렬로 계산하고 번째 인자에서 병렬로 처리한 결과들을 모두 통합해서 반환하고자 하는 타입으로 반환하고자  
사용된다.
 
만약 단순하게 입력된 여러 person age값을 뽑아  병렬로  덧셈처리한 결과를 반환하고 싶을 경우에는 다음과 같이 처리하는게 더욱 효과적이다.




1
2
3
4
5
6
7
public static void main(String args[]) {
    
    List<WedulObject> objects = Arrays.asList(new WedulObject("kim"1"dev"), new WedulObject("jun"2"insa"), new WedulObject("jung"3"kakao"));
    
    int ageSum = objects.stream().filter(x -> x.getAge() > 2).mapToInt(WedulObject::getAge).sum();
    System.out.println(ageSum);
}
cs


댓글()

Java8 스트림(Stream) API

JAVA/Java 8|2018. 5. 31. 07:35

Java8의 람다식, 인터페이스의 변화에 이어서

더 좋은 기능이 바로 스트림이다.

스트림(Stream) 정의

- 스트림이란 리눅스에서 사용되는 파이프 라인 처럼 한번에    만들어지는 연속적인 데이터 항목들의 모임이다.
Ex) ps -ef | grep pnp | grep -v drop
 
조금  자세히 설명하면집계 연산을 지원하는 요소의 순서(a sequence of elements from a source that supports aggregate operations라고 소개 되어 있다.

- Stream은 정의된 엘리먼트의 속성에 따라서 처리할 수 있는 인터페이스를 제공하지만 실제 엘리먼트들을 저장하지 않고 계산하는 데만 쓰인다.

- 스트림은 컬렉션배열, I/O 리소스 등에서 제공받은 데이터를 가지고 작업을 처리 한다.
Stream 함수형 프로그래밍 같은 처리 방법도 지원한다. (filter, map, reduce, find, match, sorted )
 
기존의 Collection 처리 방법과 Stream 처리방식과 구분되는 기본적인 특징이 두가지가 있다
Internal iteration : 명시적으로 반복작업을 수행해야 되는 Collection과 비교 하면 Stream 작업은 내부에서 처리된다

Pipelining : 많은 Stream 기능들이 Stream 자기 자신을 리턴 한다이 방식은 처리 작업이 체인처럼 연결되어 큰 파이프라인처럼 동작 하도록 한다이를 통해 앞에 연산 동작이 종료  후에야 다음 동작이 진행 되도록 하는 laziness 방식을 이용하여 효율적인 방식으로 코딩을   있다.



스트림(Stream) 소개와 Collection 단점
 
Java 8에서 스트림이 나오기 전에 Collection 이용하여 자료를 데이터를 만들고 처리하는데 사용하였다.
 
극단적인 예를 들어 현재 과일 상품들의 가격을 정렬하여 보고 싶을 경우 기존의 경우에는 Collection 사용하여 다음과 같이
 
많은 작업이 필요했다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String args[]) {        
        WedulObject[] temp = {
            new WedulObject("kim"1"manage"), new WedulObject("jung"2"insa"), new WedulObject("jun"3"dev")
        };
        
        List<WedulObject> objects = Arrays.asList(temp);
        
        // 기존의 방식
        Collections.sort(objects, new Comparator<Object>() {
            @Override
            public int compare(Object obj1, Object obj2) {
                WedulObject ob1 = (WedulObject) obj1;
                WedulObject ob2 = (WedulObject) obj2;
                return ob1.getName().compareTo(ob2.getName());
            }
        });
        
        for (WedulObject obj : objects) {
            System.out.println(obj.getName());
        }
    }
cs




그러나 java8에서 스트림을 통해 편리하게 작업을 진행   있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String args[]) {
        
        WedulObject[] temp = {
            new WedulObject("kim"1"manage"), new WedulObject("jung"2"insa"), new WedulObject("jun"3"dev")
        };
        
        List<WedulObject> objects = Arrays.asList(temp);
        
        // 기존의 방식
        Collections.sort(objects, new Comparator<Object>() {
            @Override
            public int compare(Object obj1, Object obj2) {
                WedulObject ob1 = (WedulObject) obj1;
                WedulObject ob2 = (WedulObject) obj2;
                return ob1.getName().compareTo(ob2.getName());
            }
        });
        
        for (WedulObject obj : objects) {
            System.out.println(obj.getName());
        }
        
        //strem을 이용한 정렬, 추출, 반환 
        List rare = objects.stream().sorted(Comparator.comparing(WedulObject::getAge)).map(WedulObject::getName).collect(Collectors.toList());
        rare.stream().forEach(System.out::println);
}
cs



품목(content)로 부터 stream()메서드를 사용해서 stream을 가져오고 그 다음에 여러가지 기능(sortedmap, collect)를 체인 처럼 엮어서 데이터를 처리하여 Collection 사용할  보다 더욱 간편하게 데이터를 처리   있게 되었다





또한 기존의 Collection 이용할 때의
 
기존의 코드는  못된 점은 없지만 코드의 병렬화가 어렵다는 한계점이 있다.

그러나 stream()에서는 
 
stream() parallelStream()으로 변경함으로써 병렬처리가 가능하게 된다. Stream API는 내부적으로 멀티코어로 동작하도록 처리하고 있다.







이런 스트림 문장을 생성하는 규칙이 존재한다.
 
Stream 처리는 중개 연산(intermediate operations)라고 불리는 것을 통해 서로 연결 될 수 있다이들의 리턴 타입은 stream이기 때문에 서로 연결될 수 있다. 
 
위의 예시로 보여줬던 Stream 보면 sorted, map 통해 전달 받는 Stream값을 이용하여 서로 값을 전달 하는 것을   있다.
 
  작업은 종단 연산(terminal operations) 통해 작업을 종료할  있다처리된 결과를 List, Integer void 형태 등으로 받을  있다.
 
 단계의 스트림은 요소들을 보관하지 않고 필요할  생성하며제공 받은 데이터를 변경하는 것이 아니라 연산으로 부터 생성된 스트림을 반환한다.





중계연산 메소드 소개
Filter
->  주어진 조건값을 충족하는  만을 추출하고자   사용되는 메서드 이다.
옵션 :
- distinct : 중복을 제거한 유니크 엘리먼트를 리턴 한다.
- limit(n) : 주어진 사이즈(n)에 까지의 stream을 리턴 한다. (filter 걸러진 데이터 중에 지정한 개수
                만큼만 출력)
- skip(n) : 주어진 엘리먼트 길이 까지 제외한 stream을 리턴 한다.(처음 나온 데이터 3개를 제외하고 
                출력)






Mapping
Map : 전달받은 스트림의 값을 특정 방식으로 변경하고 싶을  사용한다
-> 입력 받은 String Stream 값을 소문자로 변경  출력 




Reduction 메소드(종단 연산)
-> 중단 연산을 통해 데이터를 생성하고 변환하였다면종단 연산을 통해 변형되고 추출된 데이터를 통해 결과 데이터를 얻을  있게 해준다.
 
종단연산을 통해서 void, boolean, list, Optional<T> 형태의 데이터를 추출   있다.
 
Optional<T> 데이터 형식
기존의 데이터가 없음을 표시할  많이 사용되던 Null NPE(Null Point Exception)오류를 발생 시켜Runtime Exception 일으키는 경우가 많이 발생한다.
Null값인 데이터를 접근해서 발생하는 이유가  다수지만 null 자체의 모호함으로 인해 발생되는 경우도 있다.


1
2
3
4
Map<String, String> map = new HashMap<String, String>();
map.put("hello", null);
map.get("hello");   // "hello" key의 value인 null을 return
map.get("nice");    // "nice" key가 없으므로 null을 return
cs



위의 경우를 보면 key에 대한 value가 null인지, key가 없어서 null을 return 한건지 return 받은 null 값을 가지고는 그 의미가 모호해져 버그를 발생시킬 때도 있다.
  
그래서 java8에서 나온 Optional 클래스는 nullable T non-null 값으로 대체시키기 위해 포함된 방법이다.

, Optional 객체는 명시적으로 null 값을 갖지 않는다.

Optional 상태
– absent : 아무 것도 포함하고 있지 않은 상태
– present : non-null 값을 갖은 상태

Optional.of(T)
– T로 받은 non-null 값을 포함하는 Optional 객체 반환, T가 null 일 경우 NPE 발생







Optional.empty()
– 아무것도 포함하고 있지 않는 absent Optional 객체 반환
Optional.ofNullable(T)
– T로 받은 값이 non-null일 경우 present로, null일 경우 absent로 처리한 Optional 객체 반환
-> 값이 null 경우 비어 있는 Optional 객체를 반환하기 때문에 NPE 오류를 예방할  있다.




boolean isPresent()
– Optional 객체가 non-null 인스턴스를 포함할 경우 true 반환




T get()
– Optional 객체가 present 일 경우 포함하고 있는 인스턴스를 반환, absent일 경우 NoSuchElementException발생




T orElse(T)
– Optional 객체의 present 값을 반환만일 값이 없을 경우 명시한 T 반환 (기본값)



댓글()

Java8 인터페이스의 정적 메소드

JAVA/Java 8|2018. 5. 30. 07:42

인터페이스의 정적 메소드
 
 Java 8 부터는 인터페이스에 정적 메소드를 추가할  있다.
원래부터 인터페이스에 정적 메소드를 추가하면 안되는 이유는 없었으나단지 추상 명세로서 변하면 안된다는 인터페이스의 정신에 어긋 나는 것으로 여겨져 금지되어 왔다.




지금 까지는 일반적으로 인터페이스와 동반하는 클래스들에 정적 메소드를 두었다.

하지만 이제는 사용이 가능하다.





'JAVA > Java 8' 카테고리의 다른 글

Java8 스트림(stream) 연산  (0) 2018.05.31
Java8 스트림(Stream) API  (0) 2018.05.31
Java8 인터페이스의 정적 메소드  (0) 2018.05.30
Java8 인터페이스 default Method (디폴트 메소드)  (0) 2018.05.30
Java8 변수 유효 범위  (0) 2018.05.30
Java8 생성자 레퍼런스  (0) 2018.05.30

댓글()