지도에서 반복 제거
하고 있었어:
for (Object key : map.keySet())
if (something)
map.remove(key);
Concurrent Modification을 실행했습니다.예외로 변경했습니다.
for (Object key : new ArrayList<Object>(map.keySet()))
if (something)
map.remove(key);
이 절차 및 맵을 변경하는 기타 절차는 동기화된 블록에 있습니다.
더 나은 해결책은 없을까?
다음으로 for 루프에서 반복기를 사용하여 엔트리를 삭제하는 코드샘플을 나타냅니다.
Map<String, String> map = new HashMap<String, String>() {
{
put("test", "test123");
put("test2", "test456");
}
};
for(Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, String> entry = it.next();
if(entry.getKey().equals("test")) {
it.remove();
}
}
Java 8 에서는, 이것을 다음과 같이 실행할 수 있습니다.
map.entrySet().removeIf(e -> <boolean expression>);
Oracle 문서:
세트는 지도에 의해 백업되므로 지도의 변경 내용이 세트에 반영되며, 그 반대의 경우도 마찬가지입니다.
실제 반복기를 사용합니다.
Iterator<Object> it = map.keySet().iterator();
while (it.hasNext())
{
it.next();
if (something)
it.remove();
}
사실, 당신은 그 일을 반복해야 할 수도 있습니다.entrySet()
대신keySet()
할 수 있을 것 같아요.
더 나은 해결책은 없을까?
물론 하나의 문장에 더 나은 방법이 있지만, 그것은 어떤 요소가 제거되는지에 따라 달라집니다.
예: 모든 요소를 제거합니다.value
는 테스트입니다.그 후, 이하를 사용합니다.
map.values().removeAll(Collections.singleton("test"));
업데이트 Java 8에서 람다 식을 사용하여 한 줄로 수행할 수 있습니다.
map.entrySet().removeIf(e-> <boolean expression> );
이 질문이 너무 오래되었다는 것은 알지만, 작업을 수행하는 더 나은 방법을 업데이트하는 것이 나쁠 것은 없습니다.
Concurrent Hash Map
를 사용할 수 있습니다.
실장하다ConcurrentMap
(이것에 의해,Map
인터페이스).
예:
Map<Object, Content> map = new ConcurrentHashMap<Object, Content>();
for (Object key : map.keySet()) {
if (something) {
map.remove(key);
}
}
이 방법을 사용하면 코드가 변경되지 않습니다.그뿐map
유형이 다릅니다.
Java 8은 반복에 대한 보다 선언적인 접근 방식을 지원합니다. 즉, 결과를 계산하는 방법보다는 원하는 결과를 지정해야 합니다.새로운 접근방식의 장점은 읽기 쉽고 오류 발생률이 낮다는 것입니다.
public static void mapRemove() {
Map<Integer, String> map = new HashMap<Integer, String>() {
{
put(1, "one");
put(2, "two");
put(3, "three");
}
};
map.forEach( (key, value) -> {
System.out.println( "Key: " + key + "\t" + " Value: " + value );
});
map.keySet().removeIf(e->(e>2)); // <-- remove here
System.out.println("After removing element");
map.forEach( (key, value) -> {
System.out.println( "Key: " + key + "\t" + " Value: " + value );
});
}
결과는 다음과 같습니다.
Key: 1 Value: one
Key: 2 Value: two
Key: 3 Value: three
After removing element
Key: 1 Value: one
Key: 2 Value: two
사용하셔야 합니다.Iterator
맵을 이동하는 동안 요소를 안전하게 제거할 수 있습니다.
나는 Paul Tomblin의 말에 동의한다.보통 키 세트의 반복기를 사용하고, 그 키의 값에 근거해 조건을 설정합니다.
Iterator<Integer> it = map.keySet().iterator();
while(it.hasNext()) {
Integer key = it.next();
Object val = map.get(key);
if (val.shouldBeRemoved()) {
it.remove();
}
}
보다 상세한 대체 방법
List<SomeObject> toRemove = new ArrayList<SomeObject>();
for (SomeObject key: map.keySet()) {
if (something) {
toRemove.add(key);
}
}
for (SomeObject key: toRemove) {
map.remove(key);
}
그리고 이것도 효과가 있을 거야
ConcurrentMap<Integer, String> running = ... create and populate map
Set<Entry<Integer, String>> set = running.entrySet();
for (Entry<Integer, String> entry : set)
{
if (entry.getKey()>600000)
{
set.remove(entry.getKey());
}
}
지도에서 키를 반복적으로 찾아 별도의 컬렉션에 저장할 수 있습니다.그런 다음 지도에서 키 집합을 제거합니다.반복하는 동안 지도를 수정하는 것은 보통 눈살을 찌푸리게 한다.지도가 매우 크면 이 아이디어가 의심스러울 수 있습니다.
Set s=map.entrySet();
Iterator iter = s.iterator();
while (iter.hasNext()) {
Map.Entry entry =(Map.Entry)iter.next();
if("value you need to remove".equals(entry.getKey())) {
map.remove();
}
}
언급URL : https://stackoverflow.com/questions/1884889/iterating-over-and-removing-from-a-map
'programing' 카테고리의 다른 글
lamda 표현식은 실행될 때마다 힙에 개체를 생성합니까? (0) | 2022.08.29 |
---|---|
C의 이중 포인터 연속성 경고 (0) | 2022.08.29 |
새로운 요소/컴포넌트를 동적으로 추가하려면 appendChild와 동등한 Vue.js를 선택하십시오. (0) | 2022.08.29 |
VueJs 2클릭이 작동하지 않는 것 같다 (0) | 2022.08.29 |
JPA와 최대 절전 모드로 mapBy를 설명할 수 있는 사람? (0) | 2022.08.29 |