JAVA 8 에서 추가된 forEach 문 사용 예제
Collection 을 돌면서 작업하는 로직을 많이 작성하는데, JAVA8 에서 Iterator 인터페이스에 default 메소드로 forEach(Consumer<? super T> action) 이 추가되었다.
public class Java8Example {
public static void main(String[] args) {
// creating sample Collection
List<Integer> myList = new ArrayList<Integer>();
for (int i = 0; i < 10; i++)
myList.add(i);
// 1
// traversing using Iterator
Iterator<Integer> it = myList.iterator();
while (it.hasNext()) {
Integer i = it.next();
System.out.println("Iterator Value::" + i);
}
// 2
// traversing using for
for (Integer i : myList) {
System.out.println("for Value::" + i);
}
// 3
// traversing through forEach method of Iterable with anonymous class
myList.forEach(new Consumer<Integer>() {
public void accept(Integer t) {
System.out.println("forEach anonymous class Value::" + t);
}
});
// 4
// traversing with Consumer interface implementation
MyConsumer action = new MyConsumer();
myList.forEach(action);
// 5
// traversing with another Consumer interface implementation
Consumer c1 = (c) -> System.out.println("accept::" + c);
myList.forEach(c1);
// 6
// traversing with lambda expression
myList.forEach((c) -> System.out.println("forEach lambda::" + c));
// 7
// traversing with method reference
myList.forEach(System.out::println);
}
}
//Consumer implementation that can be reused
class MyConsumer implements Consumer<Integer> {
public void accept(Integer t) {
System.out.println("Consumer impl Value::" + t);
}
}
JAVA8 이전까지 1,2 번 방식을 많이 사용했지만 forEach, lambda 등을 사용해서 여러가지 방식으로 구현할 수 있다. 예제는 출력하는거만 있지만 특정 조건으로 필터링을 한다고 하면 JAVA8 의 stream API 를 사용할 수 있을것이다.
루프문에서 간단하게 끝나는 것이면 6번처럼 람다식을 사용하겠지만, 반드시 모든 loop 문을 바꿔야할거 같진않다. 소스 코드 가독성도 있고 성능상의 이슈도 같이 있어서 계속 사용하면서 forEach 나 람다식을 사용하도록 해야겠다.
※
토비(Toby)님 방송 - 토비의 봄(https://www.youtube.com/watch?v=s-tXAHub6vg) 에서 나왔던 내용중에서 람다식으로 바꾸는 내용을 정리해보았다.
@Bean
public ApplicationRunner run2() {
return new ApplicationRunner() {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("run()...");
}
};
}
-> 원래 형식에서 람다식을 이용해서 이름이 중요하지 않기 때문에 "ApplicationRunner" 삭제할 수 있다.
@Bean
public ApplicationRunner run2() {
return new () {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("run()...");
}
};
}
-> 클래스도 중요하지 않기 때문에
@Bean
public ApplicationRunner run2() {
return new {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("run()...");
}
};
}
-> object 만드는 중요하지 않고 메소드만 나오면 되니깐
@Bean
public ApplicationRunner run2() {
return
public void run(ApplicationArguments args) throws Exception {
System.out.println("run()...");
}
;
}
-> 메소드에서도 이름이 중요하지 않고 return 타입도 필요없어서
@Bean
public ApplicationRunner run2() {
return
(ApplicationArguments args) {
System.out.println("run()...");
}
;
}
-> 나머지로 실행하는 코드를 작성하면
@Bean
public ApplicationRunner run2() {
return
(ApplicationArguments args) -> {
System.out.println("run()...");
}
;
}
-> 자바가 인자 타입을 알기 때문에 "ApplicatoinArguments" 도 삭제할 수 있다.
@Bean
public ApplicationRunner run2() {
return
(args) -> {
System.out.println("run()...");
}
;
}
-> 한줄만 하면 되니깐 {} 를 지울 수 있다.
@Bean
public ApplicationRunner run2() {
return
(args) -> System.out.println("run()...");
}
-> parameter 가 하나라서 (args) 도 바꿀 수 있다.
@Bean
public ApplicationRunner run() {
return args -> System.out.println("run()...");
}
또다른 예
Runnable r = new Runnable(){
@Override
public void run() {
System.out.println("My Runnable");
}};
-> Runnable 이 Functional 인터페이스여서(FunctionalInterface 어너테이션을 가진 인터페이스) run() 메소드 하나만 존재하기 때문에, 다 빼고 메소드 인자와 비지니스 로직만 남긴다.
Runnable r1 = () -> {
System.out.println("My Runnable");
};
-> 메소드의 구현부분이 System.out.println() 한줄로만 되어 있어서 {} 제거할 수 있다.
Runnable r1 = () -> System.out.println("My Runnable");
도움 받은 사이트
http://www.techempower.com/blog/2013/03/26/everything-about-java-8/
https://www.journaldev.com/2389/java-8-features-with-examples
'Thinking > Study' 카테고리의 다른 글
[내용 정리] 토비의 봄 TV 5회 (0) | 2017.11.22 |
---|---|
[내용 정리] 토비의 봄 TV 1회 Double dispatch example (0) | 2017.11.17 |
Apache ZooKeeper (0) | 2017.03.22 |
패턴 정리 (0) | 2015.08.24 |
python 출력 테스트 (0) | 2015.08.21 |