Java의 유형 목록과 유형 ArrayList
(1) List<?> myList = new ArrayList<?>();
(2) ArrayList<?> myList = new ArrayList<?>();
(1)에서는 List 인터페이스의 실장을 교환할 수 있는 것으로 알고 있습니다.(1)은 필요에 관계없이 어플리케이션에서 사용되는 것 같습니다(저 자신도 항상 사용하고 있습니다).
혹시 (2)를 사용하는 사람이 있습니까?
또한, 실제로 (1)/2를 사용해야 하는 상황(예시를 얻을 수 있는 경우)은 얼마나 자주입니까?(2)는 충분하지 않습니다.인터페이스나 베스트 프랙티스 등에 대한 코딩은 별도로 합니다.)
항상 ★★★★★★★★★★★★★★★.List
ArrayList
"Discription"은List
다른 코드 베이스에 영향을 주지 않고로 변환할 수 있습니다.
「」를 하고 있는 경우ArrayList
List
이렇게 수 ArrayList
의 실장LinkedList
은 '왜냐하면'이기 때문입니다.ArrayList
코드 베이스에서는, 재구성이 필요한 특정의 방법이 사용되고 있습니다.
도 이 글을 수 있습니다.List
여기에 실장해 주세요.
「 」로 할 수 .ArrayList
그러나 곧 다른 구현이 더 적절한 선택임을 알게 됩니다.
혹시 (2)를 사용하는 사람이 있습니까?
네, 하지만 좋은 이유(IMO)가 있는 경우는 거의 없습니다.
사람들은 왜냐하면 을 사용했기 때문이다.ArrayList
했어야 할 때List
:
음음음 like like like like like like like like like like like 의 효용
Collections.singletonList(...)
★★★★★★★★★★★★★★★★★」Arrays.asList(...)
하지 않다ArrayList
.의
List
API는 동일한 유형의 목록을 반환하는 것을 보장하지 않습니다.
예를 들어, 누군가가 화상을 입은 경우, https://stackoverflow.com/a/1481123/139985에서 포스터는 "화상"에 문제가 있었습니다. 왜냐하면ArrayList.sublist(...)
ArrayList
의 를 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ArrayList
그는 를 새로운 서브리스트로 했다.ArrayList
.
「」의을 둘 가 있는 .List
'동작'을 합니다.RandomAccess
더 나빠요.아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.
또한 실제로 (1)을 (2)에 대해 사용해야 하는 빈도는 얼마나 됩니까? ((2)로 충분치 않을 경우)「인터페이스에의 대응」이나 베스트 프랙티스 등)을 참조해 주세요.
질문의 "얼마나 자주" 부분은 객관적으로 대답할 수 없다.
(예를 들어주세요)
에 따라서는 에서 「」의가 있는 경우가 .ArrayList
에 없는 APIList
예를 API.ensureCapacity(int)
,trimToSize()
★★★★★★★★★★★★★★★★★」removeRange(int, int)
('ArrayList')을public
이것이 인터페이스 IMO가 아닌 클래스를 코딩하는 유일한 건전한 이유입니다.
(이론적으로는 퍼포먼스가 약간 향상될 가능성이 있습니다.어떤 상황에서는...플랫폼에 따라 다르지만 마지막 0.05%가 필요하지 않는 한 이 작업은 수행할 가치가 없습니다.이것은 타당한 이유가 아닙니다, IMO).
랜덤 액세스가 효율적인지 여부를 모르면 효율적인 코드를 작성할 수 없습니다.
그것은 타당한 지적입니다.그러나 Java는 이를 해결하기 위한 더 나은 방법을 제공합니다.
public <T extends List & RandomAccess> void test(T list) {
// do stuff
}
를 실장하지 않은 을 했을 .RandomAccess
컴파일 오류가 발생합니다.
을 사용하다instanceof
...어색한 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★또, 리스트가 랜덤 액세스를 서포트하고 있는지 아닌지에 따라, 다른 알고리즘(동적)을 사용하는 코드를 작성할 수도 있습니다.
:ArrayList
is is is that that that that that that that that that that that that that that that that that that that that that that that를 구현하는 .RandomAccess
기타는 다음과 같습니다.CopyOnWriteList
,Stack
★★★★★★★★★★★★★★★★★」Vector
.
이 같은 을 하는 본 이 있다.Serializable
)List
(실장하지 않습니다)...하지만 위의 접근법도 이 문제를 해결합니다.(런타임 타입을 사용하여 해결 가능한 범위까지).안ArrayList
시리얼화할 수 없는 요소가 있으면 시리얼화는 실패합니다).
마지막으로 '멋있으니까'라고 말하지 않겠습니다.이 "이성"은 순환적인 논쟁("왜 "좋은 스타일"인가?")인 동시에 미제시(아마도 존재하지 않을 것이다!)에 호소하는 것입니다.('좋은 스타일'이라고 누가 그래?)
(인터페이스에 프로그래밍하는 것은 좋은 스타일이라고 생각합니다만, 그 이유를 설명하지는 않겠습니다.진정한 이유를 이해하고 스스로 올바른 결론을 내리는 것이 좋습니다.콘텍스트에 따라서는, 올바른 결론이 항상 같은 것은 아닐 수도 있습니다.
를 들어, ''를 수 .LinkedList
하시는 어플리케이션에는 이지만, 에 '어플리케이션'을 결정합니다.ArrayList
퍼포먼스상의 이유로 더 좋은 선택이 될 수 있습니다.
용도:
List list = new ArrayList(100); // will be better also to set the initial capacity of a collection
대신:
ArrayList list = new ArrayList();
참조용:
(대부분 컬렉션 다이어그램용으로 게시)
에 대한 참조를 저장하는 것은 좋은 스타일로 간주됩니다.HashSet
★★★★★★★★★★★★★★★★★」TreeSet
▼에 [설정] 설정
Set<String> names = new HashSet<String>();
한 .TreeSet
★★★★★★ 。
또한 집합에서 작동하는 메서드는 Set 유형의 매개 변수를 지정해야 합니다.
public static void print(Set<String> s)
그 후, 이 메서드를 모든 세트 실장에 사용할 수 있습니다.
이론적으로 링크드 리스트에도 같은 권장사항을 제시해야 합니다.즉, 링크드 리스트 참조를 타입 리스트의 변수에 저장하는 것입니다. 목록 에서 공통입니다.ArrayList
및LinkedList
클래스. 특히 링크 리스트에는 매우 비효율적이지만 랜덤 액세스에 대한 get 및 설정 메서드가 있습니다.
랜덤 액세스가 효율적인지 여부를 모르면 효율적인 코드를 작성할 수 없습니다.
이것은 표준 라이브러리에서 심각한 설계 오류이며, 이러한 이유로 List 인터페이스를 사용하는 것은 권장할 수 없습니다.
얼마나 하려면 , 「 」의 소스 해 주세요.binarySearch
Collections 클래스의 메서드.이 메서드는 List 매개 변수를 사용하지만 연결된 목록에 대해 이진 검색이 의미가 없습니다.그런 다음 코드가 서투르게 목록이 연결된 목록인지 여부를 검색한 다음 선형 검색으로 전환합니다.
Set
와 「」를 참조해 주세요.Map
적절하게 설계되어 있기 때문에, 그것들을 사용할 필요가 있습니다.
코드가 목록의 "소유자"인 경우 (2)를 사용합니다.이는 예를 들어 로컬 전용 변수에 해당됩니다. 추상형을 .List
ArrayList
유권을른 、 [ 른른 、 。
public class Test {
// This object is the owner of strings, so use the concrete type.
private final ArrayList<String> strings = new ArrayList<>();
// This object uses the argument but doesn't own it, so use abstract type.
public void addStrings(List<String> add) {
strings.addAll(add);
}
// Here we return the list but we do not give ownership away, so use abstract type. This also allows to create optionally an unmodifiable list.
public List<String> getStrings() {
return Collections.unmodifiableList(strings);
}
// Here we create a new list and give ownership to the caller. Use concrete type.
public ArrayList<String> getStringsCopy() {
return new ArrayList<>(strings);
}
}
쓸 때List
가 「」, 「」를 실장하고 있는 을 알 수 있습니다List
오브젝트가 속한 클래스는 지정하지 않습니다.
쓸 때ArrayList
오브젝트 클래스를 크기 조정 가능한 배열로 지정합니다.
따라서 첫 번째 버전은 향후 코드를 더욱 유연하게 만들 수 있습니다.
Java 문서 보기:
클래스 - 크기 조정 가능한 어레이 구현List
인터페이스입니다.
인터페이스 - 순서부 컬렉션(시퀀스라고도 함).이 인터페이스의 사용자는 목록의 각 요소가 삽입되는 위치를 정확하게 제어할 수 있습니다.
Array
- 단일 유형의 고정 개수의 값을 저장하는 컨테이너 객체.
나는 (2)를 사용하는 사람들은 리스코프 대체 원리나 의존성 반전 원리를 모른다고 생각한다.아니면 정말 이걸 사용해서ArrayList
.
사실 (2)가 선호될 뿐만 아니라 의무적인 경우도 있는데, 아무도 여기서 이것을 언급하지 않는 것에 매우 놀랐습니다.
시리얼화!
.ArrayList
이유는List
가 되지 않습니다.java.io.Serializable
분명히 대부분의 사람들은 연재가 필요하지 않고 이것에 대해 잊어버린다.
예:
public class ExampleData implements java.io.Serializable {
// The following also guarantees that strings is always an ArrayList.
private final ArrayList<String> strings = new ArrayList<>();
(3) Collection myCollection = new ArrayList<?>();
저는 이걸 주로 쓰고 있어요.그리고 List 메서드가 필요한 경우에만 List를 사용합니다.Array List와 동일합니다.항상 더 좁은 인터페이스로 전환할 수 있지만 더 넓은 인터페이스로 전환할 수는 없습니다.
다음 두 가지 중 하나:
(1) List<?> myList = new ArrayList<?>();
(2) ArrayList<?> myList = new ArrayList<?>();
이치노요.List
전용으로,할 수 있습니다.List
★★LinkedList
특정 되는 것입니다.따라서 특정 구현에서 분리할 수 있습니다.이제 언급할 가치가 있는 두 가지 포인트가 있습니다.
혹시 (2개)를 사용하고 계신 분이 계신가요?
네, 가끔 읽습니다(거의 안 읽어요.구현의 일부인 방법이 필요한 경우ArrayList
인터페이스의 일부가 아닌List
.예를들면ensureCapacity
.
또, 실제로 (1)/2 를 사용할 필요가 있는 경우는, 어느 정도의 빈도로(또, 예를 들어 주세요) 있습니까?
대부분의 경우 옵션 (1)을 선호합니다.이것은 OOP의 고전적인 설계 패턴으로, 특정의 실장이나 프로그램으로부터 인터페이스로의 코드 분리를 항상 시도합니다.
리스트는 인터페이스입니다.방법이 없어요.List 참조로 메서드를 호출하면 실제로는 두 경우 모두 ArrayList 메서드를 호출합니다.
그리고 미래를 위해 당신은 변할 수 있다.List obj = new ArrayList<>
로.List obj = new LinkList<>
또는 목록인터페이스를 실장하는 다른 타입.
누군가가 이것을 다시 물어보아서 나는 이 문제에 대해 좀 더 깊이 파고들었다.
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
ArrayList<String> aList = new ArrayList<String>();
aList.add("a");
aList.add("b");
}
바이트 코드 뷰어(http://asm.ow2.org/eclipse/index.html) 를 사용)를 사용하는 경우는, 리스트의 스니펫에 대해서 다음의(리스트의 초기화 및 할당만이 표시됩니다).
L0
LINENUMBER 9 L0
NEW ArrayList
DUP
INVOKESPECIAL ArrayList.<init> () : void
ASTORE 1
L1
LINENUMBER 10 L1
ALOAD 1: list
LDC "a"
INVOKEINTERFACE List.add (Object) : boolean
POP
L2
LINENUMBER 11 L2
ALOAD 1: list
LDC "b"
INVOKEINTERFACE List.add (Object) : boolean
POP
목록에는 다음과 같이 입력합니다.
L3
LINENUMBER 13 L3
NEW java/util/ArrayList
DUP
INVOKESPECIAL java/util/ArrayList.<init> ()V
ASTORE 2
L4
LINENUMBER 14 L4
ALOAD 2
LDC "a"
INVOKEVIRTUAL java/util/ArrayList.add (Ljava/lang/Object;)Z
POP
L5
LINENUMBER 15 L5
ALOAD 2
LDC "b"
INVOKEVIRTUAL java/util/ArrayList.add (Ljava/lang/Object;)Z
POP
차이점은 리스트는 INVOCK INTERFACE를 호출하는 반면, aList는 INVOCK Virtual을 호출하는 것입니다.Bycode Outline Plugin 참조를 어코드하면
invoke interface는 Java 인터페이스 내에서 선언된 메서드를 호출하기 위해 사용됩니다.
가상 호출 중
는 인터페이스 방식(invokestatic 인터페이스를 사용), 스태틱 방식(invokestatic을 사용) 및 에 의해 처리되는 몇 가지 특수한 경우를 제외한 모든 방식을 호출합니다.
요약하면 invoke interface의 경우 virtual pop objectref를 스택에서 꺼냅니다.
인터프리터는 오퍼랜드 스택에서 'n' 항목을 팝합니다. 여기서 'n'은 바이트 코드에서 가져온 8비트 부호 없는 정수 파라미터입니다.이러한 항목 중 첫 번째 항목은 메서드가 호출되는 개체에 대한 참조인 objectref입니다.
올바르게 이해했다면 기본적으로 각 방법이 objectref를 가져오는 방법에 차이가 있습니다.
GWT를 사용하면 애플리케이션 설치 공간이 줄어들기 때문에 (2)가 더 나을 수 있다는 것을 알고 있는 유일한 사례는 GWT를 사용하는 경우입니다(내 생각은 아니지만 구글 웹 툴킷 팀에서 그렇게 말합니다).그러나 JVM 내에서 실행되는 일반 Java의 경우 (1)가 항상 더 나을 수 있습니다.
1이 바람직하다고 생각합니다만,
- ArrayList에서의 옵션 동작*의 실장에 의존하고 있습니다.이 경우 ArrayList를 명시적으로 사용하는 것이 보다 명확합니다.
- ArrayList가 필요한 메서드 호출에서는 ArrayList를 사용합니다(옵션 동작 또는 퍼포먼스 특성).
제 생각엔 99%의 경우 List를 통해 그럭저럭 버틸 수 있을 것 같습니다.
- 예를 들어.
removeAll
, 또는add(null)
List
인터페이스에는 몇 가지 다른 클래스가 있습니다.ArrayList
그리고.LinkedList
.LinkedList
인덱스된 컬렉션을 작성하기 위해 사용됩니다.ArrayList
- 정렬된 목록을 만듭니다.따라서 인수에 어떤 것이든 사용할 수 있지만 코드나 라이브러리 등을 사용하는 다른 개발자가 사용하는 목록뿐만 아니라 다른 유형의 목록을 사용할 수 있도록 허용할 수 있습니다.
ArrayList<Object> myMethod (ArrayList<Object> input) {
// body
}
와만 사용할 수 있습니다.ArrayList
,것은 아니다.LinkedList
단, 다음 중 하나를 사용할 수 있습니다.List
이 메서드가 사용되고 있는 다른 장소의 클래스는 사용자가 선택할 수 있기 때문에 인터페이스를 사용하면 다음과 같이 할 수 있습니다.
List<Object> myMethod (List<Object> input) {
// body
}
이 메서드 인수에서는 다음 중 하나를 사용할 수 있습니다.List
사용할 클래스:
List<Object> list = new ArrayList<Object> ();
list.add ("string");
myMethod (list);
결론:
가능하면 어디에서나 인터페이스를 사용합니다.또, 자신이나 다른 사람이 사용하고 싶은 다른 방법을 사용하도록 제한하지 말아 주세요.
언급URL : https://stackoverflow.com/questions/2279030/type-list-vs-type-arraylist-in-java
'IT이야기' 카테고리의 다른 글
클릭 시 vue js get html5 특성 (0) | 2022.06.02 |
---|---|
Vue.js - 요소 UI - 동적 규칙 검증 양식 (0) | 2022.06.01 |
코드 흐름을 시각화하는 도구(C/C++) (0) | 2022.06.01 |
입력된 텍스트 필드의 아이콘에서 사용 가능을 클릭합니다. (0) | 2022.06.01 |
Vuex 어레이에서 특정 항목 제거 (0) | 2022.06.01 |