분류 전체보기 50

[Effective Java] item11 - equals를 재정의하려거든 hashCode도 재정의하라.

equals를 재정의하려거든 hashCode도 재정의하라! 앞에서 equals를 재정의했다. 이제 대부분의 Collection에서 내가 새로 만든 클래스를 잘 사용할 수 있다. 문제는 '대부분'이라는 것이다. 전부가 아니라! HashMap을 떠올려 보자. 이 친구는 값을 어떻게 삽입하고, 삭제하고, 탐색할까? 바로 해시다. 그런데 우리는 equals만 재정의 했기 때문에 equals로 같은 인스턴스라 할 지라도 hashCode 상에선 다른 인스턴스로 취급 될 수 있다! (사실 Object에서 정의된 hashCode를 보면 물리적으로 다른 객체는 모두 hashCode도 다르다.) 기본적인 규약 Object 명세의 규약을 잠시 살펴보자. equals 비교에 사용되는 정보가 변경되지 않았다면, 애플리케이션이 ..

Programming/Java 2021.02.12

[Effective Java] item10 - equals는 일반 규약을 지켜 재정의하라.

equals는 일반 규약을 지켜 재정의하라! 다른 언어를 쓰다가 Java로 넘어가게 되면 가장 많이 헷갈려하는 것이 String을 비교할 때다. String str1 = "Hello"; String str2 = "Hello"; System.out.println(str1 == str2); 보통 저렇게 쓰고 "어?? 왜 안되는 걸까???" 이러고 앉아 있다. 당연히 이 글을 읽을 수준이 된다면 왜 안되는지 너무나도 쉽게 알 것이다. equals 가 그 답이다. 일반적으로 객체를 생성할 때는 Object에서 final로 정의하지 않는 것들을 오버라이딩 해서 사용하는게 일반적이다. (equals, hashCode, toString, clone, finalize) 그런데 대부분 equals을 오버라이딩 할 때 I..

Programming/Java 2021.02.10

백준 문제 풀이 (2.1 ~ 2.8)

시간은 안나지만 최대한 시간을 투자해서 문제를 풀려고 노력하고는 있다.... 푼 문제 중에서 플레급 문제만 적어보았다. #9345 - 디지털 비디오 디스크 (DVDs) 재밌는 세그먼트 트리 문제였다. 임의의 칸 두개를 지정하고, 해당 범위의 값을 구한다고 가정해보자. 순서에 상관없이 값만 존재하면 OK이기 때문에, 구간을 대표할 수 있는 값을 찾아야 할 것이다. 간단하게 생각해보면 구간합/최댓값/최솟값이 있을텐데, 곰곰히 생각해보면 최댓값/최솟값 두개만 있으면 해결할 수 있다. 예를 들어, 2~6번째 칸의 최댓값이 6이고, 최솟값이 2라면 그 사이의 값은 반드시 3, 4, 5라는 것이 보장된다. 따라서 최댓값 세그먼트 트리, 최솟값 세그먼트 트리를 각각 만들어서 해결하면 된다. #16975 - 수열과 쿼..

[Effective Java] item9 - try-finally 보다는 try-with-resource를 사용하라.

try-finally 보다는 try-with-resource를 사용하라! 백준을 자바로 풀면 bufferedReader를 참 많이 사용할 것이다. 사실 단순히 문제를 푸는거라 close를 안하고 제출하는 소스가 많긴 한데, 어쨌든 close를 통해 직접 닫아줘야 한다. 위에서 말했던 것 처럼 수많은 코드가 저걸 그냥 안 닫고 넘겨버리는 경우가 있는데, 이런 경우엔 예측 불가능한 성능 문제로 이어지곤 한다. 앞에서 finalizer를 설명하면서 안전 장치로 사용할 수 있다곤 말했는데, 이 친구는 썩 좋은 친구는 아니라서... static String doReader(String path) throws IOException { BufferedReader br = new BufferedReader(new Fi..

Programming/Java 2021.02.06

[Effective Java] item8 - finalizer와 cleaner 사용을 피하라.

finalizer와 cleaner 사용을 피하라! 공부하면서 느낀거지만, 내용이 꽤나 어렵다. 같이 스터디 하는 현업자분들도 실제로 GC를 강제로 발생시키는 경우는 사실상 없다고 말했기에, 이론적인 내용이라고 생각하고 접근해보려고 한다. 본인은 자바를 처음 공부할 때 이상민씨의 "자바의 신"으로 공부를 했었는데, 거기서 finalize()를 소개하면서, 절대 사용하지 말라고 (엄밀히 말하면 java.lang에 있는 finalization()이 각각의 Object의 finalize()를 실행 시킨다는 말을 하면서) 강조했었다. 사실 초보자를 위한 책인 만큼 그냥 쓰지 말라면 쓰지 말라고 생각했는데, 이번 절에서 마침 해당 내용이 나와서 좀 좋긴 했다. 일반적인 GC는 우리가 모르는 사이에 발생하지만, fi..

Programming/Java 2021.02.05

[Effective Java] item7 - 다 쓴 객체 참조를 해제하라.

다 쓴 객체 참조를 해제하라! 때는 2018년... 다른 학과였던 나는 자료구조 수업을 들었다. 사실 시험을 잘봐서 그렇지, 과제는 엉망이었다. 7번 중 0점이 2개... 눈물났다. 그땐 "아... 코딩에 재능이 없나?" 라고 생각하고 그랬었다. (지금은 재능의 문제가 아니라 노력으로 충분히 커버할 수 있는 부분이라고 생각한다!) TMI는 집어 치우고, 그때 작성했던 Stack 자료구조의 코드를 읽어보자. class Stack { private String [] data; private final int size; private int top; public Stack(int s) { data = new String[s]; size = s; top = -1; } public boolean isEmpty()..

Programming/Java 2021.02.01

[Effective Java] item6 - 불필요한 객체 생성을 피하라.

불필요한 객체 생성을 피하라! 앞에서도 여러번 이야기 했지만, 객체를 새로 만들바엔 이미 있는 객체를 재활용 하는 것이 성능이 훨씬 좋다. (정적 팩토리 메소드에서 다뤘듯이, 굳이 Boolean 생성자를 일일히 만들 바엔 valueOf를 써서 있는걸 그대로 리턴하는 것이 좋다.) public long TestCaseOne() { long beforeTime; long afterTime; beforeTime = System.currentTimeMillis(); for(int i = 0; i < 1000000; i++) { String s = new String("I'm always learning..."); s.toUpperCase(); } afterTime = System.currentTimeMillis..

Programming/Java 2021.01.28

[Effective Java] item5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라.

자원을 직접 명시하지 말고 의존 객체 주입을 사용하라! 전국 피자집의 목록을 받아, 특정 지역에 있는 가게만 출력하는 클래스를 설계한다고 하자. 딱히 객체가 필요하진 않을 것 같고, 메소드만 적절히 활용하는 유틸리티 클래스를 만들어보자. import java.util.List; public class RegionFoods { private static final Food pizza = new Food(); private RegionFoods() {} // 객체 생성 방지 public static boolean isRegion(String food) {} public static List regionList() {} } 만약에 치킨집도 받고, 중국집도 받고 그래야 한다면 어떡할까? 당장 지금 생성한 클래스..

Programming/Java 2021.01.28

[Effective Java] item4 - 인스턴스화를 막으려거든 private 생성자를 사용하라.

인스턴스화를 막으려거든 private 생성자를 사용하라! 정적 메소드와 정적 필드'만' 담은 클래스를 만들어보자. 솔직히 객체지향에서 이러면 욕먹기 딱 좋지만, 그런데 쓸데는 있을 것이다. (ex. java.lang.Math) 그리고 final 클래스와 관련한 메소드를 모을때도 상속해서 사용하는 것은 불가능하니 별개의 클래스로 빼기도 한다. 당연히 이런 클래스는 인스턴스를 만들어서 쓰려고 설계한게 아닌데... 일반적으로 생성자를 명시하지 않으면 자연스럽게 기본 생성자가 만들어진다. 이러면 의도치 않은 작업이 발생할 수 있으니 매우 위험하다! 그래서 그 대안으로 추상 클래스를 만들었다! public abstrct class test { public int Iamfree() { return 1; } } 완벽..

Programming/Java 2021.01.25

[Effective Java] item3 - private 생성자나 열거 타입으로 싱글턴임을 보증하라.

private 생성자나 열거 타입으로 싱글턴임을 보증하라! 이 글을 읽는 사람이라면 싱글턴 클래스에 대해서 알거라고 믿...지 말고 그래도 한번 짚고 넘어가자. 싱글턴 (Singleton)이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. 싱글턴을 만드는 방식은 일반적으로 두가지이다. 각각의 예시를 보자. public class LeaveMeAlone { public static final LeaveMeAlone PLEASE = new LeaveMeAlone(); private LeaveMeAlone() {} public void dontBortherMe() { System.out.println("Hew..."); } } 일반적인 방법이다. private 생성자는 초기화 과정에 딱 한번 호출되..

Programming/Java 2021.01.21