java
[Java] 위도/경도 값에 BigDecimal or double?
[Java] 위도/경도 값에 BigDecimal or double?
2024.04.30위/경도 값을 저장할 때 BigDecimal을 사용하는 것을 본 적이 있다.하지만 BigDecimal을 사용하는 것이 좋은걸까? double을 사용하는 건 좋지 않은 걸까?BigDecimal과 double에 어떤 특징이 있는지, 위경도에 어느 자료형이 적합할지 한 번 살펴보자. double의 부동소수점 문제오늘날 컴퓨터는 대부분 IEEE 754 부동 소수점 방식을 사용하기 때문에 Java에서 double을 사용해 소수를 표현한다면 소수점 약 15자리부터 오차가 발생할 수 있다. 오차를 해결하려면?Java에는 BigDecimal이라는 자료형으로 부동소수점 방식으로 인해 생기는 오차를 막을 수 있다. https://docs.oracle.com/javase/8/docs/api/java/math/BigDec..
[Java] utility class는 무엇으로 구현하는 것이 좋을까?
[Java] utility class는 무엇으로 구현하는 것이 좋을까?
2024.04.15Utility class? utility class(유틸리티 클래스)는 애플리케이션 전체에서 활용할 수 있는 클래스로 정적 메소드(static method)를 통해 구현한다. Interface의 static method 사용? Java 8 이후로, interface에 static method를 사용할 수 있게 되었다. 만약 static method를 사용하여 유틸리티 클래스를 구현한다면 다음과 같이 작성할 수 있다. public interface CalculatorUtils { static int getSumResult(int a, int b) { return a + b; } } 인터페이스로 구현하니 간결하고 실용적이게 보인다. 하지만 인터페이스로 유틸리티 클래스를 구현하는 데에는 몇 가지 단점이 있다...
[Java] 제네릭(Generic)
[Java] 제네릭(Generic)
2024.03.12제네릭(Generic)? 제네릭은 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능이다. 객채 타입을 컴파일 타임에 체크하기 때문에 잘못된 형변환으로 인해 오류가 발생하는 상황을 막아주고, 형변환의 번거로움이 줄어들 수 있다. 제네릭 클래스 제네릭은 클래스와 메서드에 사용할 수 있는데, 먼저 제네릭 클래스는 클래스 명옆에 와 같이 타입 변수를 붙여 사용한다. class Box { private T item; public void setItem(T item) { this.item = item; } public T getItem() { return this.item; } } 여기서 T는 임의로 지정한 변수명으로 T가 아닌 다른 명칭으로 지정할 수 있다. 위 코드를 ..
[Java] hashCode()
[Java] hashCode()
2023.07.02hashCode() hashCode()는 객체, 즉 Object에 정의되어 있다. hashCode()는 객체의 주소 값을 변환하여 생성한 고유한 정수 값이다. 만약 같은 객체를 참조하고 있다면 hashCode 값은 동일하게 나온다. 예시로, 다음과 같이 작성하여 출력해보면 정수값을 확인해볼 수 있다. class Person { } public class Test { public static void main(String[] args) { System.out.println(new Person().hashCode()); // ex) 798154996 } } Java의 모든 객체의 최상위 부모는 Object이므로 hashCode() 메서드를 Override하여 재정의할 수 있다. equals()와 hashCo..
[Java] Java 8 특징
[Java] Java 8 특징
2023.04.13Java SE 8 (LTS) 2014년 3월에 공개했으며 대표적인 변경 사항은 다음과 같다. 람다 표현식(Lambda Expression) 람다 표현식은 메서드로 전달할 수 있는 익명 함수를 단순화한 것이다. 람다 표현식에는 이름은 없지만, 파라미터 리스트, 바디, 반환 형식, 발생할 수 있는 예외 리스트는 가질 수 있다. Predicate p = (Apple a) -> a.getWeight(); 자세한 내용은 [람다 표현식 소개], [람다 타입/검사/추론] 이 글들을 참고하자 메서드 참조(Method Reference) 메서드 참조는 람다 표현식을 축약한 형태이다. 메서드 참조를 사용하면 람다 표현식을 더 줄일 수 있는데, 상황에 따라 가독성이 더 좋아보일 수 있다. Predicate p = Apple..
[Java] 숫자형 스트림
[Java] 숫자형 스트림
2023.04.11이전에 reduce를 활용한 코드를 살펴보았다. Optional max = numbers.stream().reduce(Integer::max); 하지만 위 코드는 박싱 비용이 있다. 즉, 내부적으로 계산하기 전에 Integer를 기본형으로 언박싱해야 한다. 그렇지만 걱정할 필요없다. 스트림은 숫자 스트림을 효율적으로 처리할 수 있도록 기본형 특화 스트림을 제공한다. 기본형 특화 스트림 Java 8에서는 IntStream, DoubleStream, LongStream 이렇게 세 가지 기본형 특화 스트림을 제공하며 합계, 최대, 최소 등을 계산하는 sum, max, min 등의 리듀싱 연산 수행 메서드도 제공한다. 또 기본형 스트림에서 다시 객체 스트림으로 복원하는 기능도 제공한다. 다만, 특화 스트림은 오..
[Java] 람다 타입 검사/추론/제약
[Java] 람다 타입 검사/추론/제약
2023.04.04타입 검사 람다가 사용되는 context를 이용해서 람다의 형식(type)을 추론할 수 있다. 어떤 context에서 기대되는 람다 표현식의 형식을 대상 형식(target type)이라고 부른다. 타입 검사 과정 다음 예시를 통해 타입 검사 과정을 확인해보자. filter(inventory, (Apple apple) -> apple.getWeight() > 150); filter 메서드의 선언을 확인한다. filter 메서드는 두 번째 파라미터로 Predicate 형식(target type)을 기대한다. Predicate은 test라는 한 개의 추상 메서드를 정의하는 함수형 인터페이스이다. test 메서드는 Apple을 받아 boolean을 반환하는 함수 디스크립터를 묘사한다. filter 메서드로 전달..
[JPA] N+1 문제
[JPA] N+1 문제
2023.04.03N+1 문제? N+1 문제란 연관 관계가 설정된 엔티티를 조회할 경우에 조회된 데이터 개수(n) 만큼 연관관계의 조회 쿼리가 추가로 발생하는 현상을 말한다. 예를 들어, Member와 여러 Member를 가지는 MemberGroup의 관계가 있다고 하자. Member와 MemberGroup Entity는 다음과 같이 구성되어 있다. @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @ManyToOne @JoinColumn(name ..
[Java] 동작 파라미터화 코드 전달하기
[Java] 동작 파라미터화 코드 전달하기
2023.03.28동작 파라미터화? 동작 파라미터화란 아직은 어떻게 실행할 것인지 결정하지 않은 코드블록을 의미한다. 이 코드 블록은 나중에 프로그램에서 호출한다. 예를 들어, 나중에 실행될 메서드의 인수로 코드 블록을 전달할 수 있다. 결과적으로 코드 블록에 따라 메서드의 동작이 파라미터화 된다. 변화하는 요구사항마다 새로운 파라미터를 받는 메서드를 만들어야 하는 상황이 생길 수 있다. 하지만 동작 파라미터화 코드를 전달하면 해결이 가능하다. 변화하는 요구사항에 대응하기 농장 재고목록 애플리케이션에서 재고 파악하는 예제를 통해 요구사항의 변화에 대응해보자. 요구사항 1. 녹색 사과만 필터링 사과 색을 정의하는 다음과 같은 Color enum이 존재한다고 가정하자 enum Color { RED, GREEN } public..
[Java] 바이트코드 조작
[Java] 바이트코드 조작
2023.03.22코드 커버리지 측정 코드 커버리지는 테스트 코드가 프로덕션 코드를 얼마나 실행했는지를 백분율로 나타내는 지표이다. 즉, 테스트 코드가 실제로 프로덕션 코드를 얼마나 검증하고 있는지를 나타낸다. 코드 커버리지를 통해 현재 작성된 테스트 코드의 수가 충분한 것인지 논의할 수 있다. 그럼 코드 커버리지 툴을 사용해서 코드 커버리지를 측정해보자. 대표적으로 JaCoCo가 있다. 여기선 JaCoCo를 통해 측정해보도록 하자. Jacoco 먼저 JaCoCo 플러그인을 추가하고 task를 설정해보자. plugins { id 'jacoco' } jacoco { toolVersion = '0.8.5' } JaCoCo Gradle 플러그인에는 다음과 같은 task가 있다. jacocoTestReport: 바이너리 커버리지..
[Java] JVM
[Java] JVM
2023.03.20JVM, JRE, JDK? 자바 프로그램을 개발하기 위해 이런 것들을 설치하는 과정을 거쳤을 것이다. 일단 검색한대로 설치하긴 했는데, 이것들은 전부 무엇이고 어떤 역할을 할까? 한 번 살펴보자. JVM(Java Virtual Machine) JVM(Java Virtual Machine)은 자바 가상 머신으로 자바 프로그램 실행 환경을 만들어주는 소프트웨어이다. JVM은 자바 바이트코드(.class)를 OS에 특화된 코드로 변환(interpreter, JIT compiler)하여 실행시켜준다. 이 때문에 JVM을 사용하면 모든 플랫폼에서 동작하도록 할 수 있다. 즉, 플랫폼에 영향을 받지 않는다는 말이다. 여기서 주의할 점은 Java는 어떠한 JVM에서도 동작시킬 수 있기 때문에 플랫폼에 의존적이지 않지..
[Java] abstract class vs interface
[Java] abstract class vs interface
2023.01.20abstract class에 대해 공부하다가 interface와의 차이점이 궁금하여 작성하였다. 추상 클래스(Abstract class) vs 인터페이스(Interface) 추상 클래스(Abstract class) 먼저 추상 클래스(abstract class)는 클래스 내에 추상 메서드가 하나 이상 포함된 클래스를 말한다. 클래스 안에 메서드가 하나 이상 있다면 그 클래스 앞에는 반드시 abstract 클래스명으로 표기되어야 하며 abstract와 final 키워드를 동시에 표기할 수 없다. 일반 클래스에서 추상 클래스를 상속을 받는다면 추상메서드가 있을 경우 모두 구현해주어야 한다. 인터페이스(Interface) 반면 인터페이스(interface)는 모든 메서드가 추상 메서드인 경우이다. 간단히 생각하..