Oct 16, 2018 - Java 8의 stream을 이용한 List 중복제거

Friend 라는 모델의 배열 형태에서 friend_id 를 중복을 제거해서 가져오고자

기존코드

List<String> userIdList = new ArrayList<String>();
for(Friend friend : insertList) {
   boolean isExist = false;
   if (friend != null) {
      for(String user_id : userIdList) {
         if(friend.getUser_id().equals(user_id)) {
            isExist = true;         
            break;      
         }
      }
      if(isExist == false) userIdList.add(friend.getUser_id());
   }     
}

자바8 stream 사용

List<String> userIdList = insertList.stream().map(Friend::getUser_id).distinct().collect(Collectors.toList());

참조


Oct 16, 2018 - jetbrains-day-seoul-2018

JetBrains Day 서울 2018

작년에 참석 못해서 아쉬운데, 올해에는 참석 성공. 그런데, Hall A (Java JVM 세션 ) Hall B (.NET 세션)

위 두개로 나뉘어서 진행됩니다. Java JVM 세션이지만, 거의 대부분이 코틀린관련 이야기를 하게되어, 주변 지인들은 관심이 그렇게까지는 없습니다.

10:00 - 11:30

기조연설 :

개발자의 생산성을 높이기위한 장벽 제거 - by Hadi Hariri
개발 작업에 뒷따르는 다양한 인위적인 장벽 없다고 상상해보십시오. 아무도 여러분에게 사소한 관여를 하지 않고, 심지어 아무도 출퇴근시에 쳐다 보지도 않는다고 생각해 보세요.관리자가 없다는 것, 자유롭고 이상적이지 않습니까? 모든 것이 원하는 대로 실행되고 우리는 훨씬 더 생산적이 될 것입니다.

JetBrains에서는 이러한 장벽이 많이 존재하지 않습니다. 그러나 장벽이없는 것이 항상 쉬운 것은 아닙니다. 사실 우리에게 부딛히는 외부 장벽들 없다면 또 모든게 올바르게 작동 하지는 않을 가능성이 크죠.
이 강연에서 우리는 상하 관계의 장벽이 없는 업무의 흐름에 대한 장단점을 살펴보고 이때 발생하는 특정 문제를 극복하는 방법을 살펴볼 것입니다.
사내 프로젝트지만 모두 자유롭게 코딩하는 방법을 JetBrains 에서 공유 드립니다.

소프트웨어를 모르는 대한민국 기업의 위기 - by 안영회
80년대 후반 미국에서 장비를 들여오면서 번들 형태의 소프트웨어를 수정하는 업무로 시작한 대한민국 전산실. 후배들은 90년대 중후반 웹 기술을 배우면서, 외산 소프트웨어 지원 인력이 아닌 직접 개발하는 기회를 얻었습니다. 그래서, 시작한 1세대가 험난한 시절(?)을 보내고 이제야 그 안목으로 대한민국 사회에 기여를 하고자 발언을 시작합니다. 이제는 대한민국이 소프트웨어 산업을 주도해 갈 수 있습니다. 외세의 한국 영업 파트너가 아니라 진짜 소프트웨어 만드는 사람과 기업으로 가능합니다. 우리 선조들이 만드셨던 측우기와 거북선을 소프트웨어로 다시 실현하는 그날을 꿈꾸며...

13:00 - 13:45

Kotlin - What's New - by Hadi Hariri
코틀린 1.1 버전 출시 후 시간이 많이 지났습니다. 이번 세션에서는 멀티플랫폼 프로젝트 지원 등 코틀린 개발언어의 새로운 기능들에 대해서 알아 볼 예정입니다.

14:00 - 14:45

Kotlin/Anywhere - by Hadi Hariri
Kotlin은 JVM, Android, JavaScript를 대상의 언어로 알고 계셨나요? 이제 Kotlin / Native를 사용하여 iOS, macOS, Windows, Linux와 같은 다른 플랫폼을 지원할 수 있어, 단일 프로젝트에서 여러 플랫폼을 타겟팅 할 수 있게 되었습니다. 이 세션에서는 Kotlin과 함께 멀티 플랫폼 프로젝트를 만드는 방법, 언어에서 제공하는 장점 뿐만 아니라 함께 사용할 수 있는 라이브러리에 대한 내용을 다룰 것입니다.

15:00 - 15:45

Kotlin에서 제공하는 Coroutines을 사용하는 방법 - by 권태환
Kotlin Coroutines을 소개하며, 회사 안드로이드 프로젝트에 적용한 Coroutines 적용하며 얻은 경험을 짧게 공유합니다.

16:00 - 16:45

IntelliJ Tips and Tricks - by Hadi Hariri
IntelliJ IDEA 기반의 IDE 활용시 너무나도 많은 기능들을 놓치고 있는 경우가 많습니다. 출시는 연간 3회가 되고 신규 기능들은 늘어나는데 따라가지 못하는 경우가 많죠. 가장 최신 기능중 유용한 기능들을 위주로 숨겨진 신규 기능들을 소개하는 세션을 가지려 합니다.

17:00 - 17:45

Backend.AI의 JetBrains IDE용 플러그인 개발 경험 - by 고재필
Backend.AI는 사용자가 작성한 코드를 간단한 설정만으로 Cloud자원을 이용해서 구동하고 결과를 돌려주는 머신러닝에 최적화된 PaaS입니다. 기존의 Backend.AI에서 지원하던 다양한 개발 환경 통합에 더하여 새로이 IntelliJ 기반 IDE 통합을 위해 플러그인을 제작하였습니다. IntelliJ기반 IDE를 지원하는 것과 다른 개발환경 지원간의 차이점과 플러그인을 개발하면서 알게된 것들에 대해서 이야기 하고, 한계점에 대해서 논합니다. 그리고, 실제 결과물을 이용한 로컬 개발 환경에서의 실행과 원격 자원을 이용한 실행간의 손쉬운 전환을 시연합니다.

앞으로 코틀린 관련 공부를 해봐야겠습니다.


참조


Oct 15, 2018 - 람다와 스트림

람다식

람다식은 메서드를 하나의 식(expression)으로 표현하는 것을 의미합니다.

- 객체 지향 언어보다는 함수 지향 언어에 가깝습니다.  
- 함수를 간략하면서도 명확한 식으로 표현할 수 있도록 해줍니다.  
- 메서드를 람다식으로 표현하면 메서드의 이름 및 반환 값이 없어지므로 익명 함수 라고도 합니다.   
- 람다식의 형태는 매개 변수를 가진 코드 블록이지만 런타임 시에는 익명 구현 객체를 생성합니다.  

함수형 인터페이스

함수형 인터페이스는 람다식을 다루기 위한 인터페이로 하나의 추상 메서드만 정의되어 있어야 합니다. (단, static 메서드와 default 메서드의 개수에는 제약이 없음) 단순하게 하나의 interface 를 만들고, 거기에 추상화 메소드를 만들면, 람다식이 가능하게 됩니다. 보통 new 객체를 만들 었을 때 추상화 객체에 대한 Anonymous 객체가 생성되었던 부분을 조금더 간결하게 만들어지는 것입니다.

- 함수형 인터페이스 타입의 매개변수 및 반환 타입이 함수형 인터페이스 타입이라면 람다식을 참조하는 참조변수를 매개변수로 지정하고 람다식을 가리키는 참조변수를 반환하거나 또는 람다식 자체를 반환할 수 있습니다.  
- 람다식은 Object 타입으로 형변환 할 수 없으며, 오직 함수형 인터페이스로만 형변환이 가능합니다.  
- 람다식 내에서 참조하는 지역변수는 final이 붙어 있지 않아도 상수로 간주되며, 외부 지역변수와 같은 이름의 매개변수를 허용하지 않습니다.  
- 함수형 인터페이스는 @FuntionalInterface 라는 어노테이션을 붙일 수 있습니다. (컴파일러에서 추상메서드를 갖춘 인터페이스인지 검사, javadoc 페이지에서 해당 인터페이스가 함수형 인터페이스임을 알 수 있도록 한다)

메서드 참조

저는 위의 함수형 인터페이스는 업무에서 거의 사용하고 있지는 않습니다. 오히려 static method를 호출하는 용도로 메서드 참조를 자주 사용합니다. 아직 실업무보다는 개인업무 혹은 배치쪽 작업할때 간혈적으로 사용합니다.

(a, b) -> Math.max(a, b);
Math::max

메서드를 참조해서 매개변수의 정보 및 리턴 타입을 알아내어 람다식에서 불필요한 매개 변수를 제거하는 것이 목적으로,
람다식의 매개 변수는 메서드의 매개값을 전달하는 역할만 하기 때문에 메서드 참조를 이용하면 깔끔하게 처리할 수 있습니다.

스트림

String[] strArr = {"aaa", "ddd", "ccc"};
List<String> strList = Arrys.asList(strArr);
Stream<String> strStreamArr = Arrays.stream(strArr);

스트링배열을 List배열로 바꿔주는 방법입니다. 보통 굳이 저렇게 객체를 두개나 만들 필요없이,

Stream<String> strStreamArr = Stream.of("aaa", "ddd", "ccc");

Stream.of 로 Stream 처리를 하는게 저는 편합니다. 물론 Arrays를 사용하여 java.util.Arrays.ArrayList(java.util.ArrayList 클래스와는 다른 클래스)를 리턴하여 사용할 이유가 있다면 위와같이 처리해야하지만, 보통 그냥 sort 하거나 강제적으로 변경되는 로직을 처리할 용도로만 사용하기 위해서 사용하는 부분이라 그렇게까지 처리할 이유가 없습니다.

String[] sortList = { "01", "02", "03", "04", "05" };
Stream.of(sortList).map(CodeUtils::getAdVrtsTpCode);

CodeUtils 의 static 메소드를 통해, 내가 원하는 코드값으로 변경하는 로직입니다. 예전에는 for문으로 돌리면서 일일이 mapping 처리를 해야했지만, 정말 편하게 변경이 가능합니다. 성능이라든가, 효율적인 부분에 있어, 많은 부분을 람다로 바꿔 개발하진 않겠지만, Stream 은 간혹 사용할 거 같아 약간 정리해봅니다.


참조