[우아한테크코스] 2월 19일 TIL
오늘 배운 것
- java 강의
- java 강의
- 문자열
- 문자열은 객체이지만 각 문자의 나열로 구성되므로
new String("abc")
와 같이 구현하면 서로 다른 인스턴스가 되므로 안된다. - String은 불변이기 때문에 string끼리 더하다보면 매번 새로운 String 객체를 생성한다. 여기서 메모리 할당과 해제가 반복되다 보면 메모리 손해가 있으므로 긴 문자열을 더하는 경우가 있으면 StringBuilder나 StringBuffer를 사용한다.
- bytecode 보는 법: out 에
show bytecode
- string.intern(): 이미 같은 객체를 생성하고자 하면 새로 만들지 않고 가져다 사용할 수 있다.
- JDK 5부터는 컴파일러 자체에서 StringBuilder 생성
- final 붙이면 컴파일러에서 상수로 인식하고 최적화 진행
- 시간 보기:
System.currentTimeMillis(), System.nanoTimeMillis()
- 문자열은 객체이지만 각 문자의 나열로 구성되므로
- List
- ArrayList: 메모리를 순차적으로 지정, 조회가 용이
- LinkedList: 띄엄띄엄 메모리를 연결시켜둠, 삽입, 수정, 삭제가 용이
- 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로도 사용될 여지를 두는 것이다. 추상화를 해두어 다형성을 보장한다.
- 상한/하한 와일드카드
- 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; } } }
- NullPointerException 방지를 위해
- 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(~)
단 하나의 요소를 가진 리스트를 다룰 때 사용하자