(Effective Java) 9장 일반적인 프로그래밍 원칙 (TIP - String 비교, 문자열 포매팅)
아이템 57. 지역번수의 범위를 최소화하라
- 가장 처음 쓰일 때 선언하고
- 선언과 동시에 초기화.
- 초기화 팁?[Java] Collection 초기화
아이템 58. 전통적인 for 문 보다는 for-each 문을 사용하라
- for-each를 사용하지 못하는 경우가 있긴 하다.
- 루프 돌면서 원소 찾아서 제거해야 하는 경우.
- 근데 요즘은 for문 돌지 말고
removeIf()
를 사용하는 것을 권장함.
- 근데 요즘은 for문 돌지 말고
- 루프 돌면서 원소를 변경해야 하는 경우. (인덱스로 접근해야 하는 경우)
- 병렬로 돌아야 할 때
- 루프 돌면서 원소 찾아서 제거해야 하는 경우.
아이템 59. 라이브러리를 익히고 사용하라
- 웬만한건 라이브러리에 다 있으니 잘 찾아보고 써라. 이게 대체로 직접 짜는 것 보다 퀄리티도 더 낫다.
- 그리고 라이브러리 쓸거면 제대로 알아보고 써라. 막 쓰지 말고.
아이템 60. 정확한 답이 필요하다면 float와 double은 피하라
- 대신
BigDecimal, int, long
을 써라~- 소숫점 자리수랑, 숫자랑 분리해서 저장해서 정수를 사용하거나
- 아니면 소숫점 이하 자리수가 고정되어 있으면 *100 한 정수값을 사용하거나.
- 아무튼 정수를 사용하는 것이 좋다. 돈 계산에서는 무조건.
- 실수(float, double) 비교는 == 말고
.compare()
를 사용한다.Float.NaN, -0.0f
및 특수한 부동소수 값 등을 다뤄야 하기 때문.
- 참고로 BigDecimal 쓸 때, equals는 value와 scale이 모두 동일해야 true가 반환된다. value만 보려면 compareTo를 사용해야 한다.
아이템 61. 박싱된 기본 타입 보다는 기본 타입을 사용하라
- 속도 때문에 그런것도 있고
- 실수할 여지가 늘어난다.
- 박싱된 기본 타입에
==
을 쓰면 객체의 주소 비교 가 일어나서 값이 같아도 다르다는 결과가 나온다.
- 박싱된 기본 타입에
아이템 62. 다른 타입이 적절하다면 문자열 사용을 피하라
- 당연.. 문자열에 다 때려 넣어서 substring해서 쓰거나, enum개념이 명확한걸 문자열로 쓰거나 하는 것은 지양하는 것이 좋지.
아이템 63. 문자열 연결은 느리니 주의하라
- String 연결할 때
+
연산자 써서 연결하게 되면 느리니까,StringBuilder
를 사용해라 라는 내용인데…- 프로파일링 해보니
+
연산자는Arrays.copyOf()
가 호출되면서 복사가 일어나기 때문에 매번 새로운 String 객체를 만들면서 문자열을 조합하기 때문에 느리다. - 반면
StringBuilder
는 고정길이 Buffer에 문자열을 붙여 나가다가 한 번에 toString으로 전환하기 때문에 훨씬 빠르다
- 프로파일링 해보니
하지만 단순 문자열 더하기라면,
+
연산자를 써도 컴파일러가StringBuilder
로 자동 변환해준다!!- 그러나 모든 경우 이런 변환이 일어나는 것은 아니다.
- 예를 들어, 반복문 내부에는 반드시
StringBuilder
를 써야 한다.+
연산이 빌더로 자동 변환되지 않아 매우 느리기 때문.
- 문자열 몇 개 연결하는 정도는 성능에 큰 차이가 안나므로, 취향에 따라 선택 가능하다.
- StringBuilder vs joining
- iter 방식으로 문자열 만들 때는 StringBuilder 가 유용.
- stream 방식으로 문자열 만들 때는 joining 이 유용.
비교? StringUtils를 쓰는게 보기 더 깔끔하다
1
2
3
4
StringUtils.equals(certification.getMobileOs(), "ios")
certification.getMobileOs().equals("ios")
길이는 위에가 더 길지만, 더 가독성이 좋다.
+++ NPE 방지도 된다.
문자열 포매팅
1
2
3
4
5
6
7
8
// {} 방식 문자열 포매팅
String pattern = "{0} - {1} | {2}";
Object[] arguments = {"LOG", "key1", "value1"};
String result = MessageFormat.format(pattern, arguments);
// printf-style(%) 문자열 포매팅
String.format()
하지만 + 보다 속도가 꽤나 느려서 꼭 필요할 때만 사용하는 것이 좋음.
Url 관련 스트링은 UriComponentsBuilder 를 사용할 수 있음.
- buildAndExpand() 에서 파라미터를 순서 기반으로 매칭하는 것과, Map을 넘기는 것이 가능한데… 순서기반 매칭은 내재된 fragile함이 있음.
- queryParam() 사용하는 것은 좋음. 단순 String 연결 보다 가독성에서 이점이 있음.
- https://www.baeldung.com/spring-uricomponentsbuilder
- 그 외에도 regex로 Uri를 만들면서 validation 할 수 있음. 큰 장점.
아이템 64. 객체는 인터페이스를 사용해 참조하라
- 당연함. 인터페이스를 통해 참조해야 유연성을 확보할 수 있고, 의존성을 낮출 수 있으니까
- 다만 클래스가 1개 뿐이고 더 늘어날 가능성도 거의 없는데 인터페이스로 참조하겠다고 인터페이스를 또 만드는 것은 비추. 소스트리만 지저분해짐
아이템 65. 리플렉션보다는 인터페이스를 사용하라
- 리플렉션은 강력한 기능이지만 단점이 많다
- 컴파일타임 타입 검사가 불가능하다. 리플렉션은 런타임에 정보를 가져오고자 하는거니까
- 아무래도 코드가 지저분해진다.
- 성능이 떨어진다. 리플렉션을 통해서
Method.invoke()
하는건 일반 호출보다 느리다.
- 그래서 꼭 필요한 경우에만 쓰자.
- 리플렉션을 통해서 반환받은 객체는 인터페이스나 상위 클래스에 담아서 type safety하게 다루자
아이템 66. 네이티브 메서드는 신중히 사용하라
- 당연함. 성능이나 native api가 아니라면 써야 할 이유도 없고, 네이티브로 간다고 해서 성능이 무조건 좋아지리라는 법도 없어 공수도 많이 들고, 유지보수도 어렵고, 호환성도 떨어짐… 꼭 필요한 경우가 아니라면 보통 안쓰지
아이템 67. 최적화는 신중히 하라
- 최적화를 할 때는 다음 두 규칙을 따르라.
- 첫 번째, 하지 마라.
- 두 번째, 아직 하지 마라.
- 그니까, 완전히 명백하고 최적화되지 않은 해법을 찾을 때 까지는 하지 마라.
time complexity로 접근하는 알고리즘 개선은 효과가 있는 경우가 대부분이나, 다른 부분의 최적화는 글쎄.
- 요즘은 컴퓨팅 파워도 그렇고 컴파일러 최적화도 많이 좋아져서, 최적화 한답시고 투자하는 리소스 대비 크게 효율 개선이 되지 않을 수도 있음 ㅜㅜ
- 빠른 프로그램 보다는 좋은 프로그램을 작성하라!
- 객체 지향 원칙에 따라 잘 디커플링 된 좋은 프로그램이라면, 최적화 할 때도 쉽게 접근할 수 있다.
- 좋은 프로그램이면 보통 성능도 잘 나온다
아이템 68. 일반적으로 통용되는 명명 규칙을 따르라
This post is licensed under CC BY 4.0 by the author.