Map
Java로 인터페이스를 구현하는 객체가 있고 그 안에 포함 된 모든 쌍을 반복하려면 맵을 통과하는 가장 효율적인 방법은 무엇입니까?
요소의 순서는 인터페이스에 대한 특정 맵 구현에 따라 달라 집니까?
Map
Java로 인터페이스를 구현하는 객체가 있고 그 안에 포함 된 모든 쌍을 반복하려면 맵을 통과하는 가장 효율적인 방법은 무엇입니까?
요소의 순서는 인터페이스에 대한 특정 맵 구현에 따라 달라 집니까?
답변:
Map<String, String> map = ...
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
map.values()
하거나 사용할 수 있습니다 map.keySet()
.
다른 답변을 요약하고 내가 아는 것과 결합하기 위해 10 가지 주요 방법을 찾았습니다 (아래 참조). 또한 성능 테스트를 작성했습니다 (아래 결과 참조). 예를 들어,지도의 모든 키와 값의 합계를 찾으려면 다음과 같이 쓸 수 있습니다.
사용 반복자 와 의 Map.Entry를
long i = 0;
Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, Integer> pair = it.next();
i += pair.getKey() + pair.getValue();
}
사용 의 foreach 와 의 Map.Entry를
long i = 0;
for (Map.Entry<Integer, Integer> pair : map.entrySet()) {
i += pair.getKey() + pair.getValue();
}
Java 8에서 forEach 사용
final long[] i = {0};
map.forEach((k, v) -> i[0] += k + v);
사용 keySet 반환 및 foreach 문을
long i = 0;
for (Integer key : map.keySet()) {
i += key + map.get(key);
}
사용 keySet 반환 및 반복자를
long i = 0;
Iterator<Integer> itr2 = map.keySet().iterator();
while (itr2.hasNext()) {
Integer key = itr2.next();
i += key + map.get(key);
}
사용 을 위해 와 의 Map.Entry
long i = 0;
for (Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); entries.hasNext(); ) {
Map.Entry<Integer, Integer> entry = entries.next();
i += entry.getKey() + entry.getValue();
}
Java 8 스트림 API 사용
final long[] i = {0};
map.entrySet().stream().forEach(e -> i[0] += e.getKey() + e.getValue());
Java 8 Stream API 병렬 사용
final long[] i = {0};
map.entrySet().stream().parallel().forEach(e -> i[0] += e.getKey() + e.getValue());
사용 IterableMap 의를Apache Collections
long i = 0;
MapIterator<Integer, Integer> it = iterableMap.mapIterator();
while (it.hasNext()) {
i += it.next() + it.getValue();
}
이클립스 (CS) 컬렉션의 MutableMap 사용
final long[] i = {0};
mutableMap.forEachKeyValue((key, value) -> {
i[0] += key + value;
});
성능 테스트 (모드 = AverageTime, 시스템 = Windows 8.1 64 비트, Intel i7-4790 3.60GHz, 16GB)
작은지도 (100 개 요소)의 경우 점수 0.308이 최고입니다
Benchmark Mode Cnt Score Error Units
test3_UsingForEachAndJava8 avgt 10 0.308 ± 0.021 µs/op
test10_UsingEclipseMap avgt 10 0.309 ± 0.009 µs/op
test1_UsingWhileAndMapEntry avgt 10 0.380 ± 0.014 µs/op
test6_UsingForAndIterator avgt 10 0.387 ± 0.016 µs/op
test2_UsingForEachAndMapEntry avgt 10 0.391 ± 0.023 µs/op
test7_UsingJava8StreamApi avgt 10 0.510 ± 0.014 µs/op
test9_UsingApacheIterableMap avgt 10 0.524 ± 0.008 µs/op
test4_UsingKeySetAndForEach avgt 10 0.816 ± 0.026 µs/op
test5_UsingKeySetAndIterator avgt 10 0.863 ± 0.025 µs/op
test8_UsingJava8StreamApiParallel avgt 10 5.552 ± 0.185 µs/op
요소가 10000 개인지도의 경우 37.606 점이 최고입니다.
Benchmark Mode Cnt Score Error Units
test10_UsingEclipseMap avgt 10 37.606 ± 0.790 µs/op
test3_UsingForEachAndJava8 avgt 10 50.368 ± 0.887 µs/op
test6_UsingForAndIterator avgt 10 50.332 ± 0.507 µs/op
test2_UsingForEachAndMapEntry avgt 10 51.406 ± 1.032 µs/op
test1_UsingWhileAndMapEntry avgt 10 52.538 ± 2.431 µs/op
test7_UsingJava8StreamApi avgt 10 54.464 ± 0.712 µs/op
test4_UsingKeySetAndForEach avgt 10 79.016 ± 25.345 µs/op
test5_UsingKeySetAndIterator avgt 10 91.105 ± 10.220 µs/op
test8_UsingJava8StreamApiParallel avgt 10 112.511 ± 0.365 µs/op
test9_UsingApacheIterableMap avgt 10 125.714 ± 1.935 µs/op
100000 개의 요소가있는지도의 경우 1184.767 점이 최고입니다
Benchmark Mode Cnt Score Error Units
test1_UsingWhileAndMapEntry avgt 10 1184.767 ± 332.968 µs/op
test10_UsingEclipseMap avgt 10 1191.735 ± 304.273 µs/op
test2_UsingForEachAndMapEntry avgt 10 1205.815 ± 366.043 µs/op
test6_UsingForAndIterator avgt 10 1206.873 ± 367.272 µs/op
test8_UsingJava8StreamApiParallel avgt 10 1485.895 ± 233.143 µs/op
test5_UsingKeySetAndIterator avgt 10 1540.281 ± 357.497 µs/op
test4_UsingKeySetAndForEach avgt 10 1593.342 ± 294.417 µs/op
test3_UsingForEachAndJava8 avgt 10 1666.296 ± 126.443 µs/op
test7_UsingJava8StreamApi avgt 10 1706.676 ± 436.867 µs/op
test9_UsingApacheIterableMap avgt 10 3289.866 ± 1445.564 µs/op
그래프 (지도 크기에 따른 성능 테스트)
표 (지도 크기에 따른 성능 테스트)
100 600 1100 1600 2100
test10 0.333 1.631 2.752 5.937 8.024
test3 0.309 1.971 4.147 8.147 10.473
test6 0.372 2.190 4.470 8.322 10.531
test1 0.405 2.237 4.616 8.645 10.707
test2 0.376 2.267 4.809 8.403 10.910
test7 0.473 2.448 5.668 9.790 12.125
test9 0.565 2.830 5.952 13.220 16.965
test4 0.808 5.012 8.813 13.939 17.407
test5 0.810 5.104 8.533 14.064 17.422
test8 5.173 12.499 17.351 24.671 30.403
모든 테스트는 GitHub에서 이루어 집니다.
long sum = 0; map.forEach( /* accumulate in variable sum*/);
포착 sum
한, 말보다 속도가 느려질 수있다 stream.mapToInt(/*whatever*/).sum
물론 당신은 항상 상태를 캡처 피할 수없는 중. 예를 들어,하지만 그건 reasonnable 추가 될 수있다 벤치에
AtomicInteger
문제 해결을 위해로 변경하십시오 .
x±e
사이의 간격 내에 결과가 있었음 을 의미 하므로 가장 빠른 결과 ( )는 ~ 사이 이며 가장 느린 두 번째 ( )는 ~ 사이에 있으며 결과는 여전히 겹칩니다. 이제, 가장 느린 결과를 보면 , 사이 발산하는 것을 의미하는 그리고 당신은 알고 이러한 테스트 결과는 의미가있다. x-e
x+e
1184.767±332.968
852
1518
1706.676±436.867
1270
2144
3289.866±1445.564
1844
4735
while
하는 for
것은 반복하는 다른 기술이 아닙니다. 그리고 테스트에서 테스트 사이에 이러한 차이가 있다는 사실에 놀랐습니다. 이는 테스트하려는 대상과 관련이없는 외부 요소와 테스트가 제대로 분리되지 않았 음을 나타냅니다.
Java 8에서는 새로운 람다 기능을 사용하여 깨끗하고 빠르게 할 수 있습니다.
Map<String,String> map = new HashMap<>();
map.put("SomeKey", "SomeValue");
map.forEach( (k,v) -> [do something with key and value] );
// such as
map.forEach( (k,v) -> System.out.println("Key: " + k + ": Value: " + v));
의 유형 k
및 v
컴파일러에 의해 추정되며 사용할 필요가 없다 Map.Entry
더 이상은.
쉬워요!
map.entrySet().stream()
docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html에서
예, 순서는 특정지도 구현에 따라 다릅니다.
@ ScArcher2는보다 우아한 Java 1.5 구문을 가지고 있습니다. 1.4에서는 다음과 같은 작업을 수행합니다.
Iterator entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
Entry thisEntry = (Entry) entries.next();
Object key = thisEntry.getKey();
Object value = thisEntry.getValue();
// ...
}
for
으로 구조를 for (Entry e : myMap.entrySet)
당신이 컬렉션을 수정할 수 없지만, @HanuAthena 같은 예는 당신에게 제공하기 때문에 그것이 작동합니다 언급 한 Iterator
범위. (내가 뭔가 빠진 것이 아니라면 ...)
Entry thisEntry = (Entry) entries.next();
: 인식하지 못합니다 Entry
. 그 의사 코드가 다른 것입니까?
java.util.Map.Entry
.
지도를 반복하는 일반적인 코드는 다음과 같습니다.
Map<String,Thing> map = ...;
for (Map.Entry<String,Thing> entry : map.entrySet()) {
String key = entry.getKey();
Thing thing = entry.getValue();
...
}
HashMap
표준 맵 구현이며 보장하지 않습니다 (또는 돌연변이 작업이 수행되지 않으면 순서를 변경해서는 안됩니다). SortedMap
키의 자연 순서에 따라 항목을 반환하거나 Comparator
제공된 경우을 반환합니다 . LinkedHashMap
구성 방식에 따라 게재 신청서 또는 액세스 순서로 항목을 반환합니다. EnumMap
자연 순서대로 키를 반환합니다.
(업데이트 :. 나는 이것이 더 이상 진실이라고 생각하지 않습니다 ) 참고 IdentityHashMap
entrySet
반복자는 현재 같은 반환하는 특유의 구현이 Map.Entry
의 모든 항목에 대한 인스턴스를 entrySet
! 그러나 새로운 반복자가 진행할 때마다 Map.Entry
가 업데이트됩니다.
LinkedHashMap
카운트 에만 직접 액세스합니다 . 그 통해가 iterator
, spliterator
, entrySet
, 등의 순서를 수정하지 않습니다.
반복자와 제네릭을 사용하는 예 :
Iterator<Map.Entry<String, String>> entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
String key = entry.getKey();
String value = entry.getValue();
// ...
}
Iterator
범위를 제한하려면 for 루프를 넣어야 합니다.
for (Iterator<Map.Entry<K, V>> entries = myMap.entrySet().iterator(); entries.hasNext(); ) { Map.Entry<K, V> entry = entries.next(); }
. 해당 구문을 사용하여 (변수의 가시성) 범위를 entries
for 루프로 제한합니다.
이것은 두 가지 질문입니다.
@ ScArcher2 맵의 항목을 반복하는 방법 은 완벽하게 답변 했습니다.
반복 순서는 무엇인가 -만약 당신이 단지 사용 Map
하고 엄격히 말하면, 순서 보장 은 없다 . 따라서 구현에서 제공 한 순서에 의존해서는 안됩니다. 그러나 SortedMap
인터페이스가 확장 Map
되어 원하는 것을 정확하게 제공합니다. 구현은 일관된 정렬 순서를 제공합니다.
NavigableMap
또 다른 유용한 확장입니다 -이것은 SortedMap
키 세트에서 순서대로 위치를 찾는 추가 방법입니다. 그래서 가능성이 처음부터 반복의 필요성을 제거 할 수 있습니다 - 당신은 특정 찾을 수 있습니다 entry
당신이 사용 후입니다 higherEntry
, lowerEntry
, ceilingEntry
, 또는 floorEntry
방법. 이 descendingMap
방법 은 순회 순서 를 취소 하는 명시적인 방법도 제공합니다 .
지도를 반복하는 방법에는 여러 가지가 있습니다.
다음은 맵에 백만 개의 키 값 쌍을 저장하여 맵에 저장된 공통 데이터 세트의 성능을 비교 한 것이며 맵을 반복합니다.
1) entrySet()
각 루프에 사용
for (Map.Entry<String,Integer> entry : testMap.entrySet()) {
entry.getKey();
entry.getValue();
}
50 밀리 초
2) keySet()
각 루프에 사용
for (String key : testMap.keySet()) {
testMap.get(key);
}
76 밀리 초
3) 사용 entrySet()
및 반복자
Iterator<Map.Entry<String,Integer>> itr1 = testMap.entrySet().iterator();
while(itr1.hasNext()) {
Map.Entry<String,Integer> entry = itr1.next();
entry.getKey();
entry.getValue();
}
50 밀리 초
4) 사용 keySet()
및 반복자
Iterator itr2 = testMap.keySet().iterator();
while(itr2.hasNext()) {
String key = itr2.next();
testMap.get(key);
}
75 밀리 초
나는 언급했다 this link
.
이를 수행하는 올바른 방법은 승인 된 답변을 가장 효율적으로 사용하는 것입니다. 다음 코드가 약간 깨끗해 보입니다.
for (String key: map.keySet()) {
System.out.println(key + "/" + map.get(key));
}
O(1) = 2*O(1)
하면 큰 O 표기법의 정의와 거의 같습니다 . 조금 느리게 실행되지만 복잡성 측면에서 동일하다는 점에서 맞습니다.
2
entrySet()
keySet()
Map
2
함께 이클립스 컬렉션 , 당신은 사용하는 것이 forEachKeyValue
온 방법 MapIterable
에 의해 상속 인터페이스 MutableMap
및 ImmutableMap
인터페이스와 그 구현.
MutableBag<String> result = Bags.mutable.empty();
MutableMap<Integer, String> map = Maps.mutable.of(1, "One", 2, "Two", 3, "Three");
map.forEachKeyValue((key, value) -> result.add(key + value));
Assert.assertEquals(Bags.mutable.of("1One", "2Two", "3Three"), result);
익명의 내부 클래스를 사용하여 다음과 같이 코드를 작성할 수 있습니다.
final MutableBag<String> result = Bags.mutable.empty();
MutableMap<Integer, String> map = Maps.mutable.of(1, "One", 2, "Two", 3, "Three");
map.forEachKeyValue(new Procedure2<Integer, String>()
{
public void value(Integer key, String value)
{
result.add(key + value);
}
});
Assert.assertEquals(Bags.mutable.of("1One", "2Two", "3Three"), result);
참고 : 저는 Eclipse Collections의 커미터입니다.
람다 식 자바 8
Java 1.8 (Java 8)에서는 Iterable Interface의 반복자와 유사한 집계 작업 ( Stream operations )의 forEach 메소드를 사용하여 훨씬 쉬워졌습니다 .
아래 명령문을 코드에 복사하고 HashMap 변수의 이름 을 hm 에서 HashMap 변수로 바꾸어 키-값 쌍을 인쇄하십시오.
HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>();
/*
* Logic to put the Key,Value pair in your HashMap hm
*/
// Print the key value pair in one line.
hm.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));
// Just copy and paste above line to your code.
다음은 Lambda Expression을 사용하여 시도한 샘플 코드입니다 . 이 물건은 너무 멋지다. 꼭 해봐.
HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
Random rand = new Random(47);
int i = 0;
while(i < 5) {
i++;
int key = rand.nextInt(20);
int value = rand.nextInt(50);
System.out.println("Inserting key: " + key + " Value: " + value);
Integer imap = hm.put(key, value);
if( imap == null) {
System.out.println("Inserted");
} else {
System.out.println("Replaced with " + imap);
}
}
hm.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));
Output:
Inserting key: 18 Value: 5
Inserted
Inserting key: 13 Value: 11
Inserted
Inserting key: 1 Value: 29
Inserted
Inserting key: 8 Value: 0
Inserted
Inserting key: 2 Value: 7
Inserted
key: 1 value:29
key: 18 value:5
key: 2 value:7
key: 8 value:0
key: 13 value:11
또한 Spliterator 를 사용할 수 있습니다 .
Spliterator sit = hm.entrySet().spliterator();
최신 정보
Oracle Docs에 대한 설명서 링크 포함 Lambda 에 대한 자세한 내용은 이 링크 로 이동하여 집계 작업을 읽어야 하며 Spliterator의 경우이 링크 로 이동 하십시오 .
이론적으로 가장 효율적인 방법은 Map의 구현에 따라 다릅니다. 이 작업을 수행하는 공식적인 방법은을 호출 map.entrySet()
하는 것으로 Map.Entry
, 각 집합 에는 키와 값 ( entry.getKey()
및 entry.getValue()
) 이 포함되어 있습니다 .
특유의 구현에서는 사용 여부에 따라 약간의 차이가있을 수 있습니다 map.keySet()
.map.entrySet()
또는 뭔가. 그러나 나는 누군가가 그것을 그렇게 쓰는 이유를 생각할 수 없습니다. 대부분의 경우 성능에 아무런 영향을 미치지 않습니다.
그리고 예, 순서는 구현 순서와 삽입 순서 및 기타 제어하기 어려운 요소에 따라 다릅니다.
[편집] 나는 valueSet()
원래 글을 썼지 만 entrySet()
실제로는 대답입니다.
우리는 람다 식forEach
을 받아들이 는 메소드를 얻었다 . 우리는 또한 가지고 스트림 API를. 지도를 고려하십시오.
Map<String,String> sample = new HashMap<>();
sample.put("A","Apple");
sample.put("B", "Ball");
키 반복 :
sample.keySet().forEach((k) -> System.out.println(k));
값을 반복하십시오.
sample.values().forEach((v) -> System.out.println(v));
항목 반복 (forEach 및 Stream 사용) :
sample.forEach((k,v) -> System.out.println(k + ":" + v));
sample.entrySet().stream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
System.out.println(currentKey + ":" + currentValue);
});
스트림의 장점은 원하는 경우 쉽게 병렬화 할 수 있다는 것입니다. 우리는 단순히 위 parallelStream()
대신 사용해야 stream()
합니다.
forEachOrdered
forEach
스트림 대 ?
는 forEach
만남 순서를 따르지 않으며 (정의 된 경우) 본질적으로 비결정론 적 forEachOrdered
입니다. 따라서 forEach
주문이 유지된다는 보장은 없습니다. 이것도 더 확인하십시오 .
자바 8 :
람다 식을 사용할 수 있습니다.
myMap.entrySet().stream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
});
자세한 내용은 다음을 수행 하십시오 .
myMap.forEach( (currentKey,currentValue) -> /* action */ );
훨씬 간결합니다.
지도에서 한 수 반복 이상 keys
및 / 또는 values
및 / 또는 both (e.g., entrySet)
하나의 관심처럼 IN_에 따라 달라집니다
keys -> keySet()
지도를 반복합니다 .
Map<String, Object> map = ...;
for (String key : map.keySet()) {
//your Business logic...
}
values -> values()
지도를 반복합니다 .
for (Object value : map.values()) {
//your Business logic...
}
both -> entrySet()
지도를 반복합니다 .
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
//your Business logic...
}
_ 또한 HashMap을 반복하는 세 가지 방법이 있습니다. 그들은 아래에 있습니다 __
//1.
for (Map.Entry entry : hm.entrySet()) {
System.out.print("key,val: ");
System.out.println(entry.getKey() + "," + entry.getValue());
}
//2.
Iterator iter = hm.keySet().iterator();
while(iter.hasNext()) {
Integer key = (Integer)iter.next();
String val = (String)hm.get(key);
System.out.println("key,val: " + key + "," + val);
}
//3.
Iterator it = hm.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Integer key = (Integer)entry.getKey();
String val = (String)entry.getValue();
System.out.println("key,val: " + key + "," + val);
}
public class abcd{
public static void main(String[] args)
{
Map<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(10, "a");
testMap.put(20, "b");
testMap.put(30, "c");
testMap.put(40, "d");
for (Integer key:testMap.keySet()) {
String value=testMap.get(key);
System.out.println(value);
}
}
}
또는
public class abcd {
public static void main(String[] args)
{
Map<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(10, "a");
testMap.put(20, "b");
testMap.put(30, "c");
testMap.put(40, "d");
for (Entry<Integer, String> entry : testMap.entrySet()) {
Integer key=entry.getKey();
String value=entry.getValue();
}
}
}
Java로 Map 인터페이스를 구현하는 객체가 있고 그 안에 포함 된 모든 쌍을 반복하려면 맵을 통과하는 가장 효율적인 방법은 무엇입니까?
키 루프 효율이 앱의 우선 순위 인 경우 Map
원하는 순서대로 키를 유지 하는 구현 을 선택하십시오 .
요소의 순서는 인터페이스에 대한 특정 맵 구현에 따라 달라 집니까?
네 그럼요.
Map
구현은 특정 반복 순서를 약속하지만 다른 구현은 그렇지 않습니다.Map
키-값 쌍의 다른 순서 를 유지하는 다른 구현 .Map
Java 11과 함께 번들로 제공되는 다양한 구현을 요약 한이 표를 참조하십시오 . 특히 반복 순서 열을 확인하십시오. 클릭 / 탭하여 확대합니다.
순서를 유지하는 네 가지 Map
구현 이 있음을 알 수 있습니다 .
TreeMap
ConcurrentSkipListMap
LinkedHashMap
EnumMap
NavigableMap
상호 작용그 중 두 가지가 NavigableMap
인터페이스를 구현합니다 . TreeMap
& ConcurrentSkipListMap
.
이전 SortedMap
인터페이스는 새로운 NavigableMap
인터페이스에 의해 효과적으로 대체됩니다 . 그러나 이전 인터페이스 만 구현하는 타사 구현을 찾을 수 있습니다.
Map
키의 "자연 순서"에 따라 쌍을 정렬 하는 을 원하면 TreeMap
또는을 사용하십시오 ConcurrentSkipListMap
. "자연 질서"라는 용어는 키가 구현하는 클래스를 의미합니다 Comparable
. 에 의해 반환되는 값compareTo
메소드가 은 정렬에서 비교하는 데 사용됩니다.
정렬 순서를 유지하는 데 키가 사용되도록 사용자 정의 정렬 루틴을 지정하려면 Comparator
키 클래스에 적합한 구현을 전달 하십시오. TreeMap
또는을 사용하여을 ConcurrentSkipListMap
전달하십시오 Comparator
.
지도 쌍을지도에 삽입 한 원래 순서대로 유지하려면을 사용하십시오 LinkedHashMap
.
당신 같은 열거를 사용하는 경우 DayOfWeek
또는 Month
사용자의 키와 같이 사용하는 EnumMap
클래스를. 뿐만 아니라이 클래스 높게 는 열거에 의해 정의 된 순서대로 쌍을 유지하고, 아주 작은 메모리를 사용하도록 최적화 매우 빠르게 실행합니다. 예 DayOfWeek
를 들어,의 키는 DayOfWeek.MONDAY
반복 될 때 처음 발견되고의 키는 DayOfWeek.SUNDAY
마지막입니다.
Map
구현을 선택할 때 다음 사항도 고려하십시오.
Collections::synchronizedMap
(바람직하지 않은)로 감싸십시오 .이러한 고려 사항은 위의 그래픽 표에서 다룹니다.
EnumMap
. 처음 들었 기 때문입니다. 아마도 이것이 유용한 경우가 많이있을 것입니다.
순서는 항상 특정지도 구현에 따라 다릅니다. Java 8을 사용하면 다음 중 하나를 사용할 수 있습니다.
map.forEach((k,v) -> { System.out.println(k + ":" + v); });
또는:
map.entrySet().forEach((e) -> {
System.out.println(e.getKey() + " : " + e.getValue());
});
결과는 동일합니다 (동일한 순서). 같은 순서를 얻을 수 있도록 map이 지원하는 entrySet입니다. 두 번째는 람다를 사용할 수 있기 때문에 편리합니다. 예를 들어 5보다 큰 Integer 객체 만 인쇄하려는 경우 :
map.entrySet()
.stream()
.filter(e-> e.getValue() > 5)
.forEach(System.out::println);
아래 코드는 LinkedHashMap 및 일반 HashMap (예)을 통한 반복을 보여줍니다. 순서에 차이가 있습니다.
public class HMIteration {
public static void main(String[] args) {
Map<Object, Object> linkedHashMap = new LinkedHashMap<>();
Map<Object, Object> hashMap = new HashMap<>();
for (int i=10; i>=0; i--) {
linkedHashMap.put(i, i);
hashMap.put(i, i);
}
System.out.println("LinkedHashMap (1): ");
linkedHashMap.forEach((k,v) -> { System.out.print(k + " (#="+k.hashCode() + "):" + v + ", "); });
System.out.println("\nLinkedHashMap (2): ");
linkedHashMap.entrySet().forEach((e) -> {
System.out.print(e.getKey() + " : " + e.getValue() + ", ");
});
System.out.println("\n\nHashMap (1): ");
hashMap.forEach((k,v) -> { System.out.print(k + " (#:"+k.hashCode() + "):" + v + ", "); });
System.out.println("\nHashMap (2): ");
hashMap.entrySet().forEach((e) -> {
System.out.print(e.getKey() + " : " + e.getValue() + ", ");
});
}
}
LinkedHashMap (1) :
10 (# = 10) : 10, 9 (# = 9) : 9, 8 (# = 8) : 8, 7 (# = 7) : 7, 6 (# = 6) : 6, 5 (# = 5 ) : 5, 4 (# = 4) : 4, 3 (# = 3) : 3, 2 (# = 2) : 2, 1 (# = 1) : 1, 0 (# = 0) : 0,
LinkedHashMap (2) :
10:10, 9 : 9, 8 : 8, 7 : 7, 6 : 6, 5 : 5, 4 : 4, 3 : 3, 2 : 2, 1 : 1, 0 : 0,
해시 맵 (1) :
0 (# : 0) : 0, 1 (# : 1) : 1, 2 (# : 2) : 2, 3 (# : 3) : 3, 4 (# : 4) : 4, 5 (# : 5 ) : 5, 6 (# : 6) : 6, 7 (# : 7) : 7, 8 (# : 8) : 8, 9 (# : 9) : 9, 10 (# : 10) : 10,
해시 맵 (2) :
0 : 0, 1 : 1, 2 : 2, 3 : 3, 4 : 4, 5 : 5, 6 : 6, 7 : 7, 8 : 8, 9 : 9, 10:10,
제네릭을 사용하여 수행 할 수 있습니다.
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
Map에 대한 효과적인 반복 솔루션은 Java 5에서 Java 7까지 'for each'루프입니다.
for (String key : phnMap.keySet()) {
System.out.println("Key: " + key + " Value: " + phnMap.get(key));
}
Java 8부터는 람다 식을 사용하여 맵을 반복 할 수 있습니다. 향상된 'forEach'입니다
phnMap.forEach((k,v) -> System.out.println("Key: " + k + " Value: " + v));
람다에 대한 조건부를 작성하려면 다음과 같이 작성할 수 있습니다.
phnMap.forEach((k,v)->{
System.out.println("Key: " + k + " Value: " + v);
if("abc".equals(k)){
System.out.println("Hello abc");
}
});
//Functional Oprations
Map<String, String> mapString = new HashMap<>();
mapString.entrySet().stream().map((entry) -> {
String mapKey = entry.getKey();
return entry;
}).forEach((entry) -> {
String mapValue = entry.getValue();
});
//Intrator
Map<String, String> mapString = new HashMap<>();
for (Iterator<Map.Entry<String, String>> it = mapString.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, String> entry = it.next();
String mapKey = entry.getKey();
String mapValue = entry.getValue();
}
//Simple for loop
Map<String, String> mapString = new HashMap<>();
for (Map.Entry<String, String> entry : mapString.entrySet()) {
String mapKey = entry.getKey();
String mapValue = entry.getValue();
}
이를 수행하는 많은 방법이 있습니다. 다음은 몇 가지 간단한 단계입니다.
다음과 같은 하나의 맵이 있다고 가정하십시오.
Map<String, Integer> m = new HashMap<String, Integer>();
그런 다음지도 요소를 반복하기 위해 아래와 같은 작업을 수행 할 수 있습니다.
// ********** Using an iterator ****************
Iterator<Entry<String, Integer>> me = m.entrySet().iterator();
while(me.hasNext()){
Entry<String, Integer> pair = me.next();
System.out.println(pair.getKey() + ":" + pair.getValue());
}
// *********** Using foreach ************************
for(Entry<String, Integer> me : m.entrySet()){
System.out.println(me.getKey() + " : " + me.getValue());
}
// *********** Using keySet *****************************
for(String s : m.keySet()){
System.out.println(s + " : " + m.get(s));
}
// *********** Using keySet and iterator *****************
Iterator<String> me = m.keySet().iterator();
while(me.hasNext()){
String key = me.next();
System.out.println(key + " : " + m.get(key));
}
package com.test;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("ram", "ayodhya");
map.put("krishan", "mathura");
map.put("shiv", "kailash");
System.out.println("********* Keys *********");
Set<String> keys = map.keySet();
for (String key : keys) {
System.out.println(key);
}
System.out.println("********* Values *********");
Collection<String> values = map.values();
for (String value : values) {
System.out.println(value);
}
System.out.println("***** Keys and Values (Using for each loop) *****");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("Key: " + entry.getKey() + "\t Value: "
+ entry.getValue());
}
System.out.println("***** Keys and Values (Using while loop) *****");
Iterator<Entry<String, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) entries
.next();
System.out.println("Key: " + entry.getKey() + "\t Value: "
+ entry.getValue());
}
System.out
.println("** Keys and Values (Using java 8 using lambdas )***");
map.forEach((k, v) -> System.out
.println("Key: " + k + "\t value: " + v));
}
}