Sử dụng Java 8 và nếu bạn không muốn nhanh chóng một trường hợp List
một mình, giống như trong các gợi ý (và được chấp nhận) giải pháp
someMap.values().forEach(someList::addAll);
Bạn có thể làm tất cả bằng cách truyền với tuyên bố này:
List<String> someList = map.values().stream().flatMap(c -> c.stream()).collect(Collectors.toList());
Bằng cách này, điều thú vị cần biết, trên Java 8 phiên bản được chấp nhận có vẻ thực sự là nhanh nhất. Nó có khoảng thời gian giống như
for (List<String> item : someMap.values()) ...
và nhanh hơn so với giải pháp truyền trực tuyến thuần túy. Đây là mã kiểm tra nhỏ của tôi. Tôi rõ ràng không đặt tên cho nó chuẩn để tránh các cuộc thảo luận kết quả của sai sót điểm chuẩn. ;) Tôi làm tất cả các bài kiểm tra hai lần để hy vọng có được một phiên bản biên dịch đầy đủ.
Map<String, List<String>> map = new HashMap<>();
long millis;
map.put("test", Arrays.asList("1", "2", "3", "4"));
map.put("test2", Arrays.asList("10", "20", "30", "40"));
map.put("test3", Arrays.asList("100", "200", "300", "400"));
int maxcounter = 1000000;
System.out.println("1 stream flatmap");
millis = System.currentTimeMillis();
for (int i = 0; i < maxcounter; i++) {
List<String> someList = map.values().stream().flatMap(c -> c.stream()).collect(Collectors.toList());
}
System.out.println(System.currentTimeMillis() - millis);
System.out.println("1 parallel stream flatmap");
millis = System.currentTimeMillis();
for (int i = 0; i < maxcounter; i++) {
List<String> someList = map.values().parallelStream().flatMap(c -> c.stream()).collect(Collectors.toList());
}
System.out.println(System.currentTimeMillis() - millis);
System.out.println("1 foreach");
millis = System.currentTimeMillis();
for (int i = 0; i < maxcounter; i++) {
List<String> mylist = new ArrayList<String>();
map.values().forEach(mylist::addAll);
}
System.out.println(System.currentTimeMillis() - millis);
System.out.println("1 for");
millis = System.currentTimeMillis();
for (int i = 0; i < maxcounter; i++) {
List<String> mylist = new ArrayList<String>();
for (List<String> item : map.values()) {
mylist.addAll(item);
}
}
System.out.println(System.currentTimeMillis() - millis);
System.out.println("2 stream flatmap");
millis = System.currentTimeMillis();
for (int i = 0; i < maxcounter; i++) {
List<String> someList = map.values().stream().flatMap(c -> c.stream()).collect(Collectors.toList());
}
System.out.println(System.currentTimeMillis() - millis);
System.out.println("2 parallel stream flatmap");
millis = System.currentTimeMillis();
for (int i = 0; i < maxcounter; i++) {
List<String> someList = map.values().parallelStream().flatMap(c -> c.stream()).collect(Collectors.toList());
}
System.out.println(System.currentTimeMillis() - millis);
System.out.println("2 foreach");
millis = System.currentTimeMillis();
for (int i = 0; i < maxcounter; i++) {
List<String> mylist = new ArrayList<String>();
map.values().forEach(mylist::addAll);
}
System.out.println(System.currentTimeMillis() - millis);
System.out.println("2 for");
millis = System.currentTimeMillis();
for (int i = 0; i < maxcounter; i++) {
List<String> mylist = new ArrayList<String>();
for (List<String> item : map.values()) {
mylist.addAll(item);
}
}
System.out.println(System.currentTimeMillis() - millis);
Và đây là kết quả:
1 stream flatmap
468
1 parallel stream flatmap
1529
1 foreach
140
1 for
172
2 stream flatmap
296
2 parallel stream flatmap
1482
2 foreach
156
2 for
141
Sửa 2016/05/24 (hai năm sau):
Chạy thử nghiệm tương tự sử dụng một phiên bản thực tế Java 8 (U92) trên cùng một máy:
1 stream flatmap
313
1 parallel stream flatmap
3257
1 foreach
109
1 for
141
2 stream flatmap
219
2 parallel stream flatmap
3830
2 foreach
125
2 for
140
Có vẻ như có một spee dup để xử lý tuần tự các luồng và chi phí lớn hơn cho các luồng song song.
Có gì sai khi sử dụng vòng lặp? –
@JoshM Không có gì cả. Nhưng nếu tôi có thể sử dụng một cái gì đó được xây dựng trong, tôi nên. Tôi thường biết câu trả lời cho những loại câu hỏi này nhưng lần này thì không, vì vậy tôi nghĩ tôi sẽ hỏi. –