Overriding을 해주지 않으면 Object Class의 equals()를 사용하게되고, Object Class의 equals()는 == 연산자를 사용한 것과 같다.
해시 기반 컬렉션(HashSet, HashMap 등)은 hashCode()의 리턴값으로 비교대상을 추린 뒤, equals()로 동등성을 비교한다.
따라서, equals()나 hashCode()를 같이 Overriding 해야 객체 간의 동등성 비교가 정확히 이루어질 수 있다.
Optional.of(string) : 파라미터가 null 일 경우 NPE 을 발생시킴 (의도적으로 예외를 던지는 것)
Optional.ofNullable(string) : 파라미터가 null 일 경우 비어있는 Optional 객체를 생성
Optional.empty() : 비어있는 Optional 객체를 생성
메서드 반환타입이 Optional인 경우 : orElseThrow()
메서드 반환타입이 Optional이 아닌 경우 : Optional.ofNullable().orElseThrow()
A가 B의 내부에 대해 잘 알고있으며, B의 변화가 A에게도 쉽게 영향을 미친다 => 결합도가 높다
필드와 로직이 따로 분리되어있다 => 응집도가 낮다
이해하는 것도 중요하지만, 코드로 직접 짜보면서 손에 익히는게 중요할 것 같다.