Java
  • 스트림과 컬렉션 자바의 기존 컬렉션과 새롭게 추가된 스트림 모두 연속된 요소 형식의 값을 저장하는 자료구조의 인터페이스를 제공한다. 연속된이란, 순서와 상관없이 아무 값에나 접속하는 것이 아닌 순차적으로 접근한다는 것을 의미한다. 스트림과 컬렉션의 차이는 데이터를 언제 계산하느냐이다. 1) 컬렉션 컬렉션은 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 자료구조다. 따라서 컬렉션의 모든 요소는 컬렉션에 추가하기 전에 계산되어야한다. 2) 스트림 스트림은 요청할 때만 요소를 계산하는 고정된 자료구조이다. 스트림에 요소를 추가하거나 스트림에서 요소를 제거할 수 없다. 사용자가 요청한 값만 스트림에서 추출한다. 스트림은 생산자(producer)-소비자(consumer) 관계를 형성한다. 사용자가 데이터를..

    Read more
  • 스트림 구현

    스트림 정의 스트림이란 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소라고 할수있다. 1) 연속된 요소 특정 요소 형식으로 이루어진 연속된 값 집합의 인터페이스를 제공한다. 요소 저장 및 접근 연산이 주를 이루는 컬렉션과 다르게, 스트림은 filter, sorted, map 처럼 표현 계산식이 주를 이룬다. 컬렉션의 주제는 데이터이고 스트림의 주제는 계산이다. 2) 소스 스트림은 컬렉션, 배열, I/O 자원 등의 데이터 제공 소스로부터 데이터를 소비한다. 정렬된 컬렉션으로 스트림을 생성하면 정렬이 그대로 유지되는 것처럼, 리스트로 스트림을 만들면 스트림의 요소는 리스트의 요소와 같은 순서를 유지한다. 3) 데이터 처리 연산 스트림은 함수형 프로그래밍 언어에서 일반적으로 지원하는 연산과 데이터베..

    Read more

    스트림 구현

  • 도입 모든 자바 애플리케이션은 컬렉션을 만들고 처리하는 과정을 포함한다. 컬렉션은 대부분의 프로그래밍 작업에 사용될 정도로 어디서든 사용되어지고있다. 하지만 컬렉션을 많이 사용함에도 불구하고 완벽한 컬렉션 연산을 지원하기에는 아직까지도 부족하다. 많은 요소를 포함하는 컬렉션은 어떻게 처리해야할까? 성능을 높이려면 멀티코어 아키텍처를 활용하여 병렬로 컬렉션의 요소를 처리해야한다. 하지만 병렬 처리 코드를 구현하는 것은 단순 반복 처리 코드에 비해 복잡하고 어렵다. 이러한 복잡한 코드는 디버깅도 어렵다. 프로그래머가 귀중한 시간을 절약하고, 편리한 삶을 누릴 수 있도로 자바 언어 설계자들이 내린 결정이 바로 스트림이다. 스트림이란? 스트림은 자바 8 API에 새로 추가된 기능이다. 스트림은 데이터 컬렉션 반..

    Read more
  • 메서드 참조 메서드 참조를 이용하면 기존의 메서드 정의를 재활용해서 람다처럼 전달할 수 있다. inventory.sort(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())); 위 코드를 메서드 참조와 java.util.Comparator.comparing을 활용한 코드로 바꿔보자. // 메서드 참조의 사용 // Apple 클래스에 정의된 getWeight의 메서드 참조 // 실제로 메서드를 호출하는 것이 아니므로 괄호 생략 // 결과적으로 (Apple a) -> a.getWeight()를 축약한 것 inventory.sort(comparing(Apple::getWeight)); // = (Apple a) -> a.getWeight() 위 생..

    Read more
  • 도입 람다로 함수형 인터페이스의 인스턴스를 만들 수 있다. 하지만 람다 표현식 자체에는 어떤 함수형 인터페이스를 구현하는지의 정보가 포함되어있지 않으므로 람다의 실제 형식을 제대로 파악해야한다. 형식 검사 람다가 사용되는 context를 이용해서 람다의 형식을 추론할 수 있다. 어떤 context에서 기대되는 람다 표현식의 형식을 대상 형식이라고 부른다. 예를 들면 람다가 전달된 메서드 파라미터나 람다가 할당되는 변수에서 추론하는 것이다. List heightThan160cm = filter(inventory, (Height height) -> height.getHeight() > 160); 위 예제는 아래 순서로 형식 확인 과정을 거친다. (1) filter 메서드의 선언을 확인한다. (2) filte..

    Read more
  • 함수형 인터페이스의 사용 함수형 인터페이스는 오직 1개의 추상 메서드를 지정하고, 이 추상 메서드는 람다 표현식의 시그니처를 묘사한다. 함수형 인터페이스의 추상 메서드의 시그니처를 함수 디스크립터라고 한다. 다양한 람다 표현식을 사용하려면 공통의 함수 디스크립터를 기술하는 함수형 인터페이스 집합이 필요하다. 자바 API에 Comparable, Runnable, Callable 등의 다양한 함수형 인터페이스가 있지만 자바 8에 새로 추가된 함수형 인터페이스에 대해 알아보자. Predicate java.util.function.Predicate 인터페이스는 test라는 추상 메서드를 정의하며 test는 제네릭 형식 T의 객체를 인수로 받아 boolean 타입을 반환한다. 따로 정의할 필요 없이 바로 사용이 ..

    Read more
  • 생성자의 단점 생성자에는 제약이 하나 있는데, 선택적 매개변수가 많을 경우에 대응이 어렵다. 예를들어, 받아오는 매개변수에 따라 계속해서 생성되는 생성자의 코드를 보았을때 매개변수의 개수에 따라 호출되는 생성자를 짐작하기가 매우 혼잡해진다. 또는 생성자 호출을 위해서 설정하길 원하지않는 매개변수의 값까지 지정해줘야하는 불편함이 있다. 한 두개 정도는 괜찮을 수 있겠지만, 매개변수의 수가 늘어나게되면 걷잡을 수 없을정도가 된다. 코드를 읽을 때 각 값의 의미가 무엇인지 헷갈린다. 매개변수가 몇개인지 세어보며 항상 확인해야한다. 타입이 같은 매개변수가 연속으로 있으면 버그 발생 가능성이 높아진다. 실수로 매개변수의 순서가 바뀌더라도 컴파일러가 해당 에러를 잡지 못하여 런타임 에러로 이어지게된다. 자바빈즈 패..

    Read more
  • 함수 디스크립터 함수형 인터페이스의 추상 메서드 시그니처 = 람다 표현식의 시그니처 이다. 람다 표현식의 시그니처를 서술하는 메서드를 함수 디스크립터라고 부른다. 여기서 메서드 시그니처란, 메서드명/파라미터 순서/파라미터 타입/파라미터 개수를 의미한다. 왜 함수형 인터페이스를 인수로 받는 메서드에만 람다 표현식을 사용할 수 있을까? 언어 설계자들은 언어를 더 복잡하게 만들지 않는 방법을 선택했다. 대부분의 자바 프로그래머가 하나의 추상 메서드를 갖는 인터페이스에 이미 익숙하다. @FunctionalInterface 함수형 인터페이스에 @FunctionalInterface 어노테이션이 추가되었다. 해당 어노테이션을 선언하면 인터페이스가 함수형 인터페이스가 아니라면 컴파일 에러가 발생한다. 함수형 인터페이스..

    Read more
  • 람다표현식이란? 람다표현식은 JAVA 8에 등장하였다. 익명 클래스처럼 이름이 없는 함수이면서, 메서드를 인수로 전달할 수 있다. 메서드로 전달할 수 있는 익명함수를 단순화한 것이다. 람다 표현식에는 이름은 없지만, 파라미터 리스트, 바디, 반환 형식, 발생할 수 있는 예외 리스트를 가질 수 있다. 람다표현식의 특징 익명 = 메서드의 이름이 없다. 함수 = 메서드처럼 특정 클래스에 종속되지 않는다. 전달 = 람다 표현식을 메서드 인수로 전달하거나 변수로 저장될 수 있다. 간결성 = 익명 클래스처럼 많은 자질구레한 코드를 구현할 필요가 없다. 람다를 이용해서 간결한 방식으로 코드를 전달할 수 있다. 람다가 기술적으로 자바 8 이전의 자바로 할 수 없었던 일을 제공하는 것은 아니지만, 동작 파라미터를 이용할..

    Read more
  • LocalDateTime 클래스 / parse 메소드 LocalDateTime getDate = LocalDateTime.parse("20191022041", DateTimeFormatter.ofPattern("yyyyMMddHHmm")); LocalDateTime getDate2 = LocalDateTime.parse("201910302041", DateTimeFormatter.ofPattern("yyyyMMddHHmm")); 위 처럼, parse 메소드를 통해 String 문자열을 ‘yyyyMMddHHmm’ pattern으로 LocalDateTime 변수에 저장할 수 있다. until 메소드 long minute= getDate.until(getDate2, ChronoUnit.MINUTES); Str..

    Read more
  • NullPointerException NullPointerException은 개발자가 한번이라도 만나봤을 에러이다. 그정도로 흔하게 일어나는 에러로, 이는 “자바의 모든 객체는 NULL일 수 있다.”” 라는 말을 확인시켜준다. NullPointerExcpetion이 발생하는 경우를 예시로 보자. public static getCarInsurancename(Person pserson) { return person.getCar().getInsurance().getName(); } 위 코드에서 getCar()를 실행한 후의 값이 NULL이라면? 차가 없는 사람은 존재할 수 있다. person.getCar()의 값이 NULL인데 getInsurance()가 실행되면 여기서 NullPointerException이..

    Read more
  • 문제발생 자바 로직에서 VO의 get method를 통해 데이터를 set 해주고 있는 경우에 NullPointerExceptin 에러를 만날 수 있는 경우가 있다. 예제 StudyVO +NoteVO noteVO +PenVO penVO (penVO는 Null이다) 예시로, StudyVO 안에 NoteVO 타입의 변수와 PenVO 타입의 변수가 선언되어있다. noteVO는 Null이 아니기 때문에 noteVO안의 필드를 get 메소드를 통해 가져와도 에러가 발생하지 않는다. StudyVO studyVO = new StudyVO(); /** getNoteVO()는 studyVO가 Null이 아니므로 에러가 발생하지 않는다. */ NoteVO noteVO = studyVO.getNoteVO(); /** note..

    Read more
  • LocalDateTime jdk1.8 이상부터 사용 가능한 LocalDateTime을 사용해보자. LocalDateTime getDate = LocalDateTime.parse("20191022041", DateTimeFormatter.ofPattern("yyyyMMddHHmm")); LocalDateTime getDate2 = LocalDateTime.parse("201910302041", DateTimeFormatter.ofPattern("yyyyMMddHHmm")); 위 처럼, parse 메소드를 통해 String 문자열을 'yyyyMMddHHmm' pattern으로 LocalDateTime 변수에 저장할 수 있다. long minute= getDate.until(getDate2, ChronoUni..

    Read more
  • 날짜변환 String-> Date Format -> XMLGregorianCalendar convert -> GMT+09:00 설정 package com.java; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; public class Main { public static void main(String[] args) { String d..

    Read more
  • @Override 어노테이션의 사용 자바 코드에서 메소드에만 선언할 수 있는 @Override 어노테이션이 있다. @Override public boolean equals(Object b) { return b.test == test } 위 예제코드로 @Override 어노테이션의 의미를 설명해보자. 상위 타입의 메서드를 재정의했다는 의미인데, 위 예제의 클래스가 Object 클래스(상위 타입)의 equals 메서드를 재정의한 것이다. 기존의 Object 클래스의 equals 메서드가 아닌 해당 메서드를 재선언하여 새로 선언한 로직을 실행하겠다는 의미이다. @Override 어노테이션을 일관되게 사용하면 여러 버그들을 예방할 수 있다. @Override 메서드의 잘못된 사용 예제 main 메서드를 보면 똑..

    Read more
  • Copyright 2024. GRAVITY all rights reserved