[우아한테크코스] 2월 19일 TIL

2 minute read

오늘 배운 것

  1. java 강의

- java 강의

  1. 문자열
    • 문자열은 객체이지만 각 문자의 나열로 구성되므로 new String("abc")와 같이 구현하면 서로 다른 인스턴스가 되므로 안된다.
    • String은 불변이기 때문에 string끼리 더하다보면 매번 새로운 String 객체를 생성한다. 여기서 메모리 할당과 해제가 반복되다 보면 메모리 손해가 있으므로 긴 문자열을 더하는 경우가 있으면 StringBuilder나 StringBuffer를 사용한다.
    • bytecode 보는 법: out 에 show bytecode
    • string.intern(): 이미 같은 객체를 생성하고자 하면 새로 만들지 않고 가져다 사용할 수 있다.
    • JDK 5부터는 컴파일러 자체에서 StringBuilder 생성
    • final 붙이면 컴파일러에서 상수로 인식하고 최적화 진행
    • 시간 보기: System.currentTimeMillis(), System.nanoTimeMillis()
  2. List
    • ArrayList: 메모리를 순차적으로 지정, 조회가 용이
    • LinkedList: 띄엄띄엄 메모리를 연결시켜둠, 삽입, 수정, 삭제가 용이
  3. Generic 데이터를 특정 타입을 지정해 관리한다.
    타입 안정성 보장, 타입 체크와 형변환이 생략되어 코드 간결해진다. 예외적인 상황이 아니라면 Generic 사용
    • 상한/하한 와일드카드
      조회용: 상한, 수정/삭제용: 하한 사용
      private void test(final List<? extends Animal> animals) { //상한
       animals.add(new Dog()); //`? extends Animal`의 타입이 `Dog`이라는 보장이 없어서 에러 발생 
       //test(new ArrayList<Cat>)일지 모른다.  
      }
      private void test(final List<? super Animal> animals) { //하한   
       final Object object = animals.get(0); // 상한의 타입이 무한인지라 Object라면 무엇이든지 가능한 것
       animals.add(new Dog()); //Dog은 Animal이기 때문에 
      }
      Animal.class.cast(animals.get(0)); //캐스팅
      animals.get(0) instaceof Animal //캐스트 확인 boolean 변환
      

      와일드카드를 사용하지 않고 generic을 사용하는 경우 타입을 return 하는 등의 사용이 가능하지만, 하한이 되지 않는다.

    • 선언시에 List<String> animals = new ArrayList<>();를 사용하는 이유는 추후에 LinkedList와 같은 형식의 List로도 사용될 여지를 두는 것이다. 추상화를 해두어 다형성을 보장한다.
  4. enum
    • NullPointerException 방지를 위해 ("44".equlas(str)) 와 같은 식으로 작성하는 습관 들이기
      enum은 상수 객체의 모음, 외부에서 새로운 enum을 생성하지 못하므로 기본 생성자는 private
      valueOf()라는 메서드를 이용해 일치하는 객체를 가져오고, 그 객체에 하고 싶은 행위를 시킨다.
      if를 완전히 없앨 수는 없으므로 Collections, 다형성, 제네릭 등을 활용해 어떻게 추상화할지에 대해서 고민하자.
      PLUS("+") {
       @Override
       int caculate(int a, int b) {
         return a + b;
       }  //람다식으로 표현 가능
      }
      abstract int calculate(int a, int b);
      static Operator valueOf(final String value) {
       for(Operator operator : values()) {
         if(operator.str.equals(value)) {
             return value;
         }
       }
      }
      

- EnumMap 에 대해서

EnumMap은 Map 인터페이스에서 키를 특정 enum 타입을 삽입하도록 하는 구현체이다.
순서가 보장되고 성능이 우수하다는 장점이 있다.
애초에 HashMap을 이용해서 구현했는데 좋은 방법이 있었다.

Map<Ranking, Integer> map = new EnumMap<>(Ranking.class);

- abstract란

추상 클래스 내에 존재하는 추상 메서드로 상속을 강제하는 일종의 규제, 메서드의 시그니처만이 정의된 비어있는 메서드

abstract class Caluculator {
    int a, b;
    public abstract void sum();
    public abstract void mul();
    public void run() {
        sum();
        mul();
    }
}

class CalculatorDetail extends Caculator {
    public void sum() {
        return a + b;
    }
    public void mul() {
        return a * b;
    }
}

public static void main(String[] args) {
    CalculatorDetail c = new CalculatorDetail();
    c.run();
}

위와 같이 사용할 수 있다.
뭐랄까 인터페이스는 메서드를 다루는 느낌이라면, 이거는 클래스의 추상화를 다룬 느낌

- Collections.singletonList(~)

단 하나의 요소를 가진 리스트를 다룰 때 사용하자