java.util은 왜 안 돼?get(int 인덱스)를 설정하시겠습니까?
그럴만한 이유가 있겠지만, 누가 설명 좀 해주시겠어요?java.util.Set
인터페이스 부족get(int Index)
, 또는 이와 유사한 것get()
방법?
세트는 물건을 넣는 데 좋은 것 같습니다만, 단 한 가지도 우아하게 회수할 수 있는 방법을 찾을 수 없습니다.
첫 번째 아이템을 원하는지 알면set.iterator().next()
특정 인덱스로 항목을 가져오려면 어레이에 캐스트해야 할 것 같습니다.
세트에서 데이터를 검색하는 적절한 방법은 무엇입니까?(반복기 사용 제외)
API에서 제외된다는 것은 이것을 하지 않는 타당한 이유가 있다는 것을 의미합니다.누군가 가르쳐 주실 수 있을까요?
편집: 여기에 매우 훌륭한 답변이 몇 개 있고, 몇 개는 "더 많은 컨텍스트"라고 말합니다.구체적인 시나리오는 dbUnit 테스트입니다.이 테스트에서는 쿼리에서 반환된 세트에는 아이템이1개밖에 없다고 합리적으로 단언할 수 있었습니다.그 아이템에 접속하려고 했습니다.
다만, 이 질문은 시나리오가 없는 경우에 유효합니다.그 이유는, 다음과 같이, 보다 초점을 맞추고 있기 때문입니다.
세트와 리스트의 차이점은 무엇입니까?
아래의 멋진 답변에 감사드립니다.
왜냐하면 세트에는 순서가 없기 때문입니다.일부 실장에서는, (특히,java.util.SortedSet
interface) 단, 이는 세트의 일반 속성이 아닙니다.
이 방법으로 세트를 사용하려는 경우 대신 목록을 사용하는 것이 좋습니다.
오브젝트 관계 매핑(예를 들어 휴지 상태)을 사용하는 JavaEE 응용 프로그램을 작성할 때 이것은 반복적인 질문입니다.여기서 응답한 모든 사용자 중 Andreas Peterson만이 실제 문제를 이해하고 정답을 제시했습니다.Java는 UniqueList가 없습니다.또는 OrderSet이라고 부를 수도 있습니다.Indexed Set)을 클릭합니다.
Maxwing은 이 사용 사례(주문 및 고유 데이터 필요)를 언급하며 SortedSet을 제안했지만, Marty Pitt가 진정으로 필요로 했던 것은 아닙니다.
이 "IndexedSet"은 SortedSet과 동일하지 않습니다.SortedSet에서는 요소가 비교기(또는 "자연적" 순서)를 사용하여 정렬됩니다.
단, LinkedHashSet에 가깝습니다(다른 사람들도 제안했습니다).또한 요소를 삽입했을 때와 같은 순서로 반환할 수 있기 때문에 (또한 존재하지 않는) ArrayListSet에 가깝습니다.
그러나 Linked Hash Set은 구현일 뿐 인터페이스가 아닙니다.필요한 것은 IndexedSet(또는 ListSet, OrderedSet, UniqueList) 인터페이스입니다.이것에 의해, 프로그래머는, 특정의 순서가 있어 중복되지 않는 요소의 컬렉션이 필요한 것을 지정하고, 그 후, 어떠한 실장(예를 들면, Hibernate가 제공하는 실장)으로 인스턴스화할 수 있습니다.
JDK는 오픈 소스이기 때문에 이 인터페이스가 Java 7에 포함될 수 있습니다.
Myers의 답변에 언급되지 않은 한 가지 사항을 덧붙입니다.
첫 번째 아이템이 필요한 경우 set.iterator().next()를 사용할 수 있습니다.그렇지 않으면 특정 인덱스로 아이템을 취득하기 위해 어레이에 캐스트해야 할 것 같습니다.
세트에서 데이터를 검색하는 적절한 방법은 무엇입니까?(반복기 사용 제외)
또, 인터페이스(가장 일반적인 실장)에 대해서도 이해해 둘 필요가 있습니다.
SortedSet은 요소의 자연스러운 순서 또는 일부 요소를 사용하여 유지되는 세트(즉, 요소가 고유함)입니다.Comparator
. 를 사용하면 첫 번째 항목과 마지막 항목에 쉽게 액세스할 수 있습니다.first()
그리고.last()
방법들.aSortedSet
수집품을 복제 없이 보관하고 특정 방법으로 주문해야 할 때 가끔 유용합니다.
편집: 요소를 삽입 순서(목록과 거의 같은)로 유지하는 세트가 필요한 경우 를 참조하십시오.
이 때문에 언제 세트를 사용해야 하는지, 언제 리스트를 사용해야 하는지에 대한 의문이 생깁니다.일반적으로 다음과 같은 조언이 있습니다.
- 주문된 데이터가 필요한 경우 목록을 사용하십시오.
- 고유 데이터가 필요한 경우 Set을 사용합니다.
- 둘 다 필요한 경우 SortedSet(비교기로 정렬된 데이터의 경우) 또는 OrderedSet/UniqueList(삽입으로 정렬된 데이터의 경우) 중 하나를 사용합니다.유감스럽게도 Java API에는 아직 OrderedSet/UniqueList가 없습니다.
자주 발생하는 네 번째 사례는 둘 다 필요하지 않다는 것입니다.이 경우, 리스트와 세트를 사용하는 프로그래머가 있습니다.개인적으로 나는 순서를 정하지 않고 목록을 보는 것이 매우 해롭다고 생각한다 - 왜냐하면 그것은 완전히 다른 짐승이기 때문이다.고유성 설정이나 동등성 설정 등이 필요한 경우를 제외하고 항상 목록을 선호합니다.
정확히 이런 식으로 철자를 쓴 사람이 있는지 모르겠지만, 다음 사항을 이해해야 합니다.
세트에 '첫 번째' 요소는 없습니다.
왜냐하면 다른 사람들이 말했듯이 세트에는 순서가 없기 때문입니다.집합은 순서를 포함하지 않는 수학적 개념입니다.
물론 주문되지 않은 파일 목록을 메모리에 저장할 수는 없습니다.뭔가 순서가 있어야지.내부적으로는 어레이나 링크 리스트 같은 거죠.근데 이게 뭔지도 모르고첫 번째 요소도 없어요'첫 번째'라는 요소가 우연히 나오는 거예요다음에는 처음은 아닐 수도 있어요특정 첫 번째 요소를 "보증"하기 위한 단계를 밟아도, 우연히 특정 세트의 구현에 적합하게 되었기 때문에, 다른 구현은 수행했던 것과 같은 방식으로 작동하지 않을 수 있습니다.또, 실제로 사용하고 있는 실장에 대해서는, 생각만큼 잘 모르는 경우가 있습니다.
사람들은 RDBMS 시스템과 함께 ALL.THE.TIME을 마주치지만 이해하지 못한다.RDBMS 쿼리는 레코드 세트를 반환합니다.이것은 수학의 집합과 동일한 유형입니다. 이 경우 항목이 레코드일 때만 순서가 매겨진 항목의 집합입니다.RDBMS 쿼리 결과에는 ORDER BY 절을 사용하지 않는 한 순서가 보장되지 않지만 데이터나 코드의 모양이 약간 바뀌어 쿼리 옵티마이저가 다른 방식으로 작동하도록 트리거되고 갑자기 결과가 예상한 순서대로 나오지 않을 경우 항상 RDBMS 쿼리 결과가 나타납니다.이들은 일반적으로 데이터베이스 클래스에서 (또는 매뉴얼 또는 튜토리얼을 읽을 때) 쿼리 결과에 순서가 보장되지 않는다는 설명을 미리 받았을 때 주의를 기울이지 않았던 사람들입니다.
표준 Java 컬렉션에서 일부 데이터 구조가 누락되었습니다.
가방(세트와 유사하지만 여러 요소를 포함할 수 있음)
Unique List(순서 목록, 각 요소를 한 번만 포함할 수 있음)
이 경우 유니켈리스트가 필요할 것 같습니다.
유연한 데이터 구조가 필요한 경우 Google 컬렉션에 관심이 있을 수 있습니다.
맞습니다. 집합 집합의 요소는 집합 집합 집합의 정의에 따라 정렬되지 않습니다.따라서 인덱스로 액세스할 수 없습니다.
그런데 인덱스를 파라미터로 제공하는 것이 아니라 우리가 찾고 있는 것과 동일한 오브젝트를 get(object) 메서드를 사용하면 어떨까요?이것에 의해, 같은 방법으로 사용되는 요소의 속성을 아는 것만으로, 세트내의 요소의 데이터에 액세스 할 수 있습니다.
집합에서 인덱스별로 많은 랜덤 액세스를 수행할 경우 해당 요소의 배열 보기를 얻을 수 있습니다.
Object[] arrayView = mySet.toArray();
//do whatever you need with arrayView[i]
단, 다음과 같은 두 가지 주요 단점이 있습니다.
- 전체 세트의 어레이를 작성해야 하므로 메모리 효율이 높지 않습니다.
- 세트가 변경되면 보기가 사용되지 않게 됩니다.
그 이유는 Set은 일의성만을 보증할 뿐 최적의 액세스 또는 사용 패턴에 대해서는 언급하지 않기 때문입니다.즉, 집합은 목록 또는 맵일 수 있으며, 각각 검색 특성이 매우 다릅니다.
수치 인덱스를 세트로 사용하는 유일한 이유는 반복을 위해서일 것입니다.그러기 위해서는
for(A a : set) {
visit(a);
}
실제로 인덱스를 통해 액세스할 수 있는 SortedSet을 원하는 상황에 부딪혔습니다(색인으로 정렬되지 않은 세트에 액세스하는 것은 의미가 없다는 다른 포스터에 동의합니다).예를 들어, 아이들을 분류하고 중복된 아이들을 허용하지 않는 트리가 있습니다.
그것들을 표시하기 위해서는 인덱스를 통한 액세스가 필요했고, 중복을 효율적으로 제거하기 위해 설정된 속성이 유용했습니다.
java.util이나 google 컬렉션에서 적절한 컬렉션을 찾을 수 없었기 때문에 직접 구현하기가 쉬웠습니다.기본 개념은 인덱스를 통한 액세스가 필요할 때 SortedSet을 랩하고 목록을 작성하는 것입니다(SortedSet이 변경되면 목록을 무시합니다).이 방법은 물론 랩된 SortedSet을 변경하고 목록에 액세스하는 것이 컬렉션의 수명 동안 분리된 경우에만 효율적으로 작동합니다.그렇지 않으면 자주 정렬되는 목록처럼 작동합니다. 즉, 너무 느립니다.
많은 수의 아이들이 있기 때문에 Collections.sort를 통해 분류한 목록보다 성능이 크게 향상되었습니다.
인덱스를 통해 액세스할 수 있는 기본 데이터 구조는 2개뿐입니다.
- 어레이 데이터 구조에는 인덱스를 사용하여
O(1)
달성해야 할 시간의 복잡성get(int index)
작동. - LinkedList 데이터 구조에는 인덱스를 통해 액세스할 수도 있지만
O(n)
달성해야 할 시간의 복잡성get(int index)
작동.
자바에서는ArrayList
는 어레이 데이터 구조를 사용하여 구현됩니다.
Set 데이터 구조는 보통 HashTable/HashMap 또는 Balanced를 통해 구현할 수 있습니다.요소가 존재하는지 여부를 빠르게 감지하고 존재하지 않는 요소를 추가하기 위한 트리 데이터 구조. 일반적으로 잘 구현된 집합은 다음을 수행할 수 있습니다.O(1)
시간 복잡도contains
작동.자바에서는HashSet
가장 일반적으로 사용되는 Set 실장입니다.이 실장은 콜을 통해 이루어집니다.HashMap
API 및HashMap
는 링크 리스트(Array와 Linked List의 조합)를 사용한 개별 체인을 사용하여 구현됩니다.
세트는 다른 데이터 구조를 통해 구현될 수 있으므로 없습니다.get(int index)
방법을 가르쳐 주세요.
Set 인터페이스에 get index-type 콜이나 first()나 last()와 같은 보다 기본적인 콜이 없는 이유는 이것이 애매한 조작이기 때문에 잠재적으로 위험한 조작이기 때문입니다.어떤 메서드가 세트를 반환하고 first() 메서드를 호출하면 일반적인 세트가 주문에 대해 보증을 하지 않는 경우 예상되는 결과는 무엇입니까?그 결과 오브젝트는 메서드의 호출마다 크게 다를 수 있습니다.또는 사용하고 있는 라이브러리가 실장 내용을 변경할 때까지 잘못된 보안의식에 빠질 수 있습니다.이러한 오브젝트는 특별한 이유 없이 모든 코드가 깨지는 것을 알 수 있습니다.
여기에 기재되어 있는 회피책에 대한 제안도 도움이 됩니다.색인화된 액세스가 필요한 경우 목록을 사용하십시오.a) 주문에 대한 보증이 없고 b) 후속 호출이나 다른 기본 구현에 따라 주문이 변경되지 않는다는 보장이 없기 때문에 반복기 또는 일반 집합과 함께 어레이를 사용할 때는 주의하십시오.중간에 필요한 것이 있으면 SortedSet 또는 LinkedHashSet이 좋습니다.
// 단, Set 인터페이스에 get-random-element가 있었으면 합니다.
java.util.Set
는 주문되지 않은 아이템의 컬렉션입니다.세트에 get(int 인덱스)가 있으면 의미가 없습니다. 세트에 인덱스가 없고 값만 추측할 수 있기 때문입니다.
If you really want this, code a method to get random element from Set.
If you don't mind the set to be sorted then you may be interested to take a look at the indexed-tree-map project.
The enhanced TreeSet/TreeMap provides access to elements by index or getting the index of an element. And the implementation is based on updating node weights in the RB tree. So no iteration or backing up by a list here.
Set is an interface and some of its implementation classes are HashSet, TreeSet and LinkedHashSet. It uses HashMap under the hood to store values. Because HashMap does not preserve the order, it is not possible to get value by index.
You now must be thinking how Set is using HashMap since HashMap stores a key, value pair but the Set does not. valid question. when you add an element in Set, internally, it maintains a HashMap where the key is the element you want to enter in Set and the value is the dummy constant. Below is an internal implementation of add function. Hence, all the keys in the HashMap will have the same constant value.
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
Because the Set stores unique elements in random locations and Internally It uses multiple data structures. i.e. Array, linked list, a tree with hashing.
link https://en.wikipedia.org/wiki/Set_(abstract_data_type)
You can do new ArrayList<T>(set).get(index)
To get element in a Set, i use to following one:
public T getElement(Set<T> set, T element) {
T result = null;
if (set instanceof TreeSet<?>) {
T floor = ((TreeSet<T>) set).floor(element);
if (floor != null && floor.equals(element))
result = floor;
} else {
boolean found = false;
for (Iterator<T> it = set.iterator(); !found && it.hasNext();) {
if (true) {
T current = it.next();
if (current.equals(element)) {
result = current;
found = true;
}
}
}
}
return result;
}
ReferenceURL : https://stackoverflow.com/questions/769731/why-doesnt-java-util-set-have-getint-index
'programing' 카테고리의 다른 글
Vuejs2의 선택 태그에서 계산된 v-model (0) | 2022.08.25 |
---|---|
Kotlin 소스 파일을 Java 소스 파일로 변환하는 방법 (0) | 2022.08.25 |
C/C++에 표준 기호 함수(signum, sgn)가 있습니까? (0) | 2022.08.25 |
Vuex: _이것.$store가 정의되지 않았습니다. (0) | 2022.08.25 |
정렬된 두 어레이를 정렬된 어레이로 병합하려면 어떻게 해야 합니까? (0) | 2022.08.25 |