Trong khi tôi đang thực hiện một bài tập lập trình nhỏ, tôi đã tình cờ gặp một số ClassCastException
. Làm nền tôi đang đưa ra một phiên bản đơn giản của việc thực hiện để chứng minh vấn đề:ClassCastException khi sử dụng nhà cung cấp bản đồ tùy chỉnh trong nhóm theo
Cho một chuỗi mà chỉ các nhân vật
A
hoặcB
chứa tính toán một bản đồ với các nhân vật như chìa khóa và số lần xuất hiện như các giá trị. Ngoài ra, bản đồ phải luôn chứa cả hai ký tự làm khóa (với giá trị bằng 0 nếu một ký tự bị thiếu trong chuỗi đầu vào).
Ví dụ:
"A" => {A=1, B=0}
"AAB" => {A=2, B=1}
giải pháp đầu tiên của tôi là như sau:
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
public Map<Character, Long> createResult(String input) {
Map<Character, Long> map = input.chars()
.mapToObj(c -> (char) c)
.collect(groupingBy(c -> c, counting()));
map.putIfAbsent('A', 0L);
map.putIfAbsent('B', 0L);
return map;
}
Giải pháp này làm việc nhưng tôi muốn thử nếu nó là pos sible để cung cấp một bản đồ với giá trị mặc định cho groupingBy
chức năng:
public HashMap<Character, Long> createResult2(String input) {
return input.chars()
.mapToObj(c -> (char) c)
.collect(groupingBy(c -> c, this::mapFactory, counting()));
}
private HashMap<Character, Long> mapFactory() {
HashMap<Character, Long> map = new HashMap<>();
map.put('A', 0L);
map.put('B', 0L);
return map;
}
Khi gọi createResult2
với đầu vào A
một ClassCastException
được ném trong thời gian chạy:
java.lang.ClassCastException: java.lang.Long cannot be cast to [Ljava.lang.Object; at java.util.stream.Collectors.lambda$groupingBy$45(Collectors.java:909) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250) at java.lang.CharSequence$1CharIterator.forEachRemaining(CharSequence.java:149) at java.util.Spliterators$IntIteratorSpliterator.forEachRemaining(Spliterators.java:1908) at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
bất cứ ai có thể giải thích tại sao điều này đang xảy ra?
Luồng có vẻ quá mức cần thiết cho sự cố đơn giản này. Thậm chí tệ hơn, stacktrace không chứa gì về mã * của bạn gây ra lỗi. Đó sẽ là lý do đủ để tôi sử dụng một vòng lặp đơn giản. –
Dòng cuối cùng trong stacktrace tương ứng với lệnh gọi 'collect' trong đoạn mã của tôi. – eee
@LutzHorn Câu hỏi này là nhiều hơn về lý do tại sao điều này xảy ra và ít hơn về cách giải quyết bài tập. – eee