remagine

알아두면 매우 편리한 자바 상식 10선 본문

JAVA

알아두면 매우 편리한 자바 상식 10선

remagine 2017. 2. 17. 16:00

이 목록에는 Java 개발자가 자주 제기하는 10 가지 실수가 요약되어 있습니다.


원문 :: http://www.programcreek.com/2014/05/top-10-mistakes-java-developers-make/ 

번역 

# 1. 배열을 ArrayList로 변환


배열을 ArrayList로 변환하기 위해 개발자는 다음을 수행합니다.

List<String> list = Arrays.asList(arr);

Arrays.asList ()는 Arrays 내의 개인용 정적 클래스 인 ArrayList를 리턴합니다. java.util.ArrayList 클래스가 아닙니다. java.util.Arrays.ArrayList 클래스는 메소드를 set (), get (), contains ()하지만 요소를 추가하는 메소드가 없으므로 크기가 고정됩니다. 실제 ArrayList를 만들려면 다음을 수행해야합니다.

ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

ArrayList의 생성자는 java.util.Arrays.ArrayList의 수퍼 유형 인 Collection 유형을 허용 할 수 있습니다.

# 2. 배열에 값이 들어 있는지 확인

개발자는 종종 다음을 수행합니다.

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
 

코드가 작동하지만 목록을 먼저 설정하여 변환 할 필요가 없습니다. 리스트를 세트로 변환하는 것은 여분의 시간이 필요합니다. 그것은 다음과 같이 간단 할 수 있습니다 :

Arrays.asList(arr).contains(targetValue);

또는

for(String s: arr){
	if(s.equals(targetValue))
		return true;
}
return false;

첫 번째 것은 두 번째 것보다 읽기 쉽습니다.

# 3. 루프 내부의 목록에서 요소 제거

반복하는 동안 요소를 제거하는 다음 코드를 고려하십시오.

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = 0; i < list.size(); i++) {
	list.remove(i);
}
System.out.println(list);

출력은 다음과 같습니다.

[b, d]

이 방법에는 심각한 문제가 있습니다. 요소가 제거되면 목록의 크기가 줄어들고 색인이 변경됩니다. 따라서 인덱스를 사용하여 루프 내부의 여러 요소를 삭제하려면 올바르게 작동하지 않습니다.

iterator를 사용하는 것이 루프 내부의 요소를 삭제하는 올바른 방법이라는 것을 알 수 있습니다. Java에서 foreach 루프는 반복자처럼 작동하지만 실제로는 그렇지 않습니다. 다음 코드를 고려하십시오.

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
 
for (String s : list) {
	if (s.equals("a"))
		list.remove(s);
}

ConcurrentModificationException 가 Throw됩니다 .

대신 다음과 같습니다.

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
	String s = iter.next();
 
	if (s.equals("a")) {
		iter.remove();
	}
}

.next()전에 호출해야 .remove()합니다. foreach 루프에서 컴파일러는 .next()요소를 제거하는 작업 후에 호출합니다 ConcurrentModificationExceptionArrayList.iterator () 의 소스 코드를 살펴볼 수 있습니다.

# 4. Hashtable 대 HashMap

알고리즘의 관례에 따라 Hashtable은 데이터 구조의 이름입니다. 그러나 Java에서 데이터 구조의 이름은 다음과 같습니다 HashMap간의 주요 차이점 중 하나 Hashtable와 HashMap즉 Hashtable동기화됩니다. 아주 자주 당신은 필요 없어 Hashtable, 대신 HashMap사용해야합니다.

HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap
Top 10 questions about Map

# 5. 콜렉션의 원시 유형 사용

Java에서는 원시 유형 및 무제한 와일드 카드 유형 을 쉽게 혼합 할 수 있습니다. Take Set for Setraw type, Set<?>제한없는 와일드 카드 유형입니다.

원시 형식 List을 매개 변수로 사용하는 다음 코드를 고려하십시오 .

public static void add(List list, Object o){
	list.add(o);
}
public static void main(String[] args){
	List<String> list = new ArrayList<String>();
	add(list, 10);
	String s = list.get(0);
}

이 코드는 예외를 throw합니다.

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at ...

원시 형식 컬렉션을 사용하면 안전하지 않은 원시 형식 컬렉션을 건너 뛰기 때문에 위험합니다. 이 사이의 큰 차이점은 SetSet<?>하고 Set<Object>
원시 형식과 제한 되지 않은 와일드 카드 및 유형 삭제를 확인하십시오 . (Raw type vs. Unbounded wildcard)

# 6. 액세스 수준

매우 자주 개발자는 클래스 필드에 public을 사용합니다. 직접 참조하여 필드 값을 쉽게 얻을 수 있지만 이것은 매우 나쁜 설계입니다. 엄지 손가락의 규칙에 따라 회원들의 액세스 수준이 최대한 낮아집니다.

public, default, protected 및 private (public, default, protected, and private)

# 7. ArrayList 대 LinkedList

때 개발자 사이의 차이를 모르는 ArrayList및 LinkedList그들은 종종 사용 ArrayList이 익숙하기 때문에. 그러나 이들 사이에는 큰 성능 차이가 있습니다. 간단히 말해, LinkedList추가 / 제거 작업이 많고 임의 액세스 작업이 많지 않은 경우 선호해야합니다. 체크 아웃 ArrayListLinkedList 이 당신에게 새로운 경우의 성능에 대한 자세한 정보를 얻을 수 있습니다.

# 8. 변경 가능 대 불변

변경 불가능한 객체에는 단순성, 안전성 등과 같은 많은 장점이 있지만 각 고유 값에 대해 별도의 객체가 필요하며 객체가 너무 많으면 가비지 수집에 높은 비용이 발생할 수 있습니다. 변경 가능과 불변 중 하나를 선택할 때 균형이 이루어져야합니다.

일반적으로 가변 객체는 너무 많은 중간 객체를 생성하지 않기 위해 사용됩니다. 하나의 고전적인 예는 많은 수의 문자열을 연결하는 것입니다. 변경할 수없는 문자열을 사용하면 가비지 수집을 즉시받을 수있는 많은 객체를 생성합니다. 이것은 변경 가능한 객체를 사용하여 CPU에 시간과 에너지를 낭비합니다 (예 :) StringBuilder.

String result = "" ; 
for ( String s : arr ) { 
	result = result + s ; 
}

변경 가능한 객체가 바람직한 다른 상황이 있습니다. 예를 들어 변경 가능한 객체를 메소드에 전달하면 너무 많은 구문 구문을 뛰어 넘지 않고 여러 결과를 수집 할 수 있습니다. 또 다른 예는 정렬과 필터링입니다. 원래 컬렉션을 취하고 정렬 된 값을 반환하는 메서드를 만들 수는 있지만 더 큰 컬렉션에서는 매우 낭비가됩니다. 스택 오버플로에 대한 dasblinkenlight의 대답 에서)

왜 String은 변경 불가능합니까?

# 9. 슈퍼와 서브의 생성자


기본 생성자가 정의되지 않았기 때문에이 컴파일 오류가 발생합니다. Java에서 클래스가 생성자를 정의하지 않으면 컴파일러는 기본적으로 해당 클래스에 대해 인수가없는 기본 생성자를 삽입합니다. 슈퍼 클래스 (이 경우 Super (String s))에 생성자가 정의되어 있으면 컴파일러에서 인수가없는 기본 생성자를 삽입하지 않습니다. 위의 Super 클래스의 상황입니다.

Sub 클래스의 생성자는 인수가 있거나 인수가없는 경우 인수가없는 Super 생성자를 호출합니다. 컴파일러는 Sub 클래스의 2 개 생성자에 super ()를 삽입하려고 시도하지만 Super의 기본 생성자는 정의되어 있지 않으므로 컴파일러는 오류 메시지를보고합니다.

이 문제를 해결하려면 간단하게 1) Super 클래스에 Super () 생성자를 추가합니다.

public Super(){
    System.out.println("Super");
}

또는 2) 자체 정의 된 Super 생성자를 제거하거나 3) super(value)하위 생성자에 추가 합니다.

슈퍼와 서브의 생성자

# 10. ""또는 생성자?

문자열은 다음 두 가지 방법으로 만들 수 있습니다.

//1. use double quotes
String x = "abc";
//2. use constructor
String y = new String("abc");

그 차이점은 무엇입니까?

다음 예제는 빠른 대답을 제공 할 수 있습니다.

String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
 
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True

그것들이 메모리에 할당되는 방법에 대한 자세한 내용은 ""또는 생성자를 사용하여 Java 문자열 생성을 확인하십시오 .

 덧붙여...

이 목록은 GitHub에서 많은 수의 오픈 소스 프로젝트를 분석 한 결과, 스택 오버 플로우 관련 질문 및 인기있는 Google 검색어를 기반으로 작성되었습니다. 그들이 최고 10 위안임을 증명할 평가는 없지만 확실히 매우 일반적입니다. 어떤 부분에 동의하지 않는다면 의견을 남겨주세요. 좀 더 일반적인 실수를 지적 해 주시면 감사하겠습니다.

'JAVA' 카테고리의 다른 글

배열(list) 제거 중 발생한 ConcurrentModificationException  (0) 2019.05.09
Comments