ConcurrentModificationException 逻辑分解
ConcurrentModificationException logic breakdown
根据文档 ConcurrentModificationException 指出:
ConcurrentModificationException 发生在不允许同时修改对象时。
我正在尝试对某些 java 概念进行除锈并制作霍夫曼压缩应用程序。
我有一个辅助函数,我认为这是造成这种情况的原因,但我不确定为什么。
当我传入 root 并将其设置为由 huffmanHelper
返回的新根时
(我的代码可能还没有完全按照我的要求去做)
我的问题: * 在幕后为什么我正在尝试 java 中的问题。*
谢谢
package huffman;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;
public class huffman {
public static Map<Character, Integer> frequency = new HashMap<Character, Integer>();
public static PriorityQueue<node> nodesPQ = new PriorityQueue<node>();
public static void main(String[] args) {
/* get input */
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
frequency = inputFrequency(frequency,input);
System.out.println(frequency);
scanner.close();
nodesPQ = createNodes(nodesPQ, frequency);
node a = nodesPQ.poll();
node b = nodesPQ.poll();
node OGroot = new node(a,b,a.getFrequency() + b.getFrequency(),null);
node finalRoot = createBranch(nodesPQ,OGroot);
finalRoot.inorderPrint();
}
/* counts occurrences of letters in output returns Map<Char, # of occurrences> */
public static Map<Character,Integer> inputFrequency(Map<Character,Integer> map,String input){
/* split input into char Array */
char[] charsArray = input.toCharArray();
/* fill hashmap ['Char', # of occurrences] */
for(char i : charsArray) {
int count = 0;
for(char j : charsArray){
if(i == j) {
count++;
}
map.put(i,count);
}
}
return map;
}
/* take Map of <Character, # of occurrences> and create nodes inside PQ*/
public static PriorityQueue<node> createNodes(PriorityQueue<node> nodePQ,Map<Character,Integer> map){
nodePQ = new PriorityQueue<>();
// create nodes inside PQ
for (Map.Entry<Character,Integer> i : frequency.entrySet()) {
Character character = i.getKey();
Integer occurrences = i.getValue();
node n = new node(null,null,occurrences,character);
nodePQ.add(n);
}
return nodePQ;
}
public static node createBranch(PriorityQueue<node> nodePQ, node root){
node newRoot = null;
for(node i : nodePQ) {
node nextFrequent = nodePQ.poll();
root = huffmanHelper(nodesPQ,root,nextFrequent);
}
return newRoot;
}
public static node huffmanHelper(PriorityQueue<node> nodePQ, node root, node nextFrequent){
node newRoot = new node(nextFrequent,root,root.getFrequency() + nextFrequent.getFrequency(),null);
//get next letter and frequency
return newRoot;
}
}
我的堆栈跟踪:
hello my name is sam
{ =4, a=2, s=2, e=2, h=1, y=1, i=1, l=2, m=3, n=1, o=1}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.PriorityQueue$Itr.next(PriorityQueue.java:536)
at huffman.huffman.createBranch(huffman.java:83) - is the start of
forLoop in createBranch
at huffman.huffman.main(huffman.java:26) - is node finalRoot =
createBranch(nodesPQ,OGroot); in main
此行从优先级队列中删除一个元素:
node nextFrequent = nodePQ.poll();
它发生在遍历相同优先级队列的循环中,因此算作禁止的并发修改。这会导致您的异常。
is there a better way you can think of iterating over a PriorityQueue
to remove items? just a regular for loop w PQ.size() ?
如果想按优先级排完队列,一直取出元素直到poll()
returns null
(代码未测试):
node nextFrequent = nodePQ.poll();
while (nextFrequent != null) {
// Do something with nextFrequent
nextFrequent = nodePQ.poll();
}
poll
方法 检索并移除此队列的头部,或者 returns null
如果此队列为空。
文档 link:Queue.poll()
根据文档 ConcurrentModificationException 指出: ConcurrentModificationException 发生在不允许同时修改对象时。
我正在尝试对某些 java 概念进行除锈并制作霍夫曼压缩应用程序。
我有一个辅助函数,我认为这是造成这种情况的原因,但我不确定为什么。
当我传入 root 并将其设置为由 huffmanHelper
(我的代码可能还没有完全按照我的要求去做)
我的问题: * 在幕后为什么我正在尝试 java 中的问题。*
谢谢
package huffman;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;
public class huffman {
public static Map<Character, Integer> frequency = new HashMap<Character, Integer>();
public static PriorityQueue<node> nodesPQ = new PriorityQueue<node>();
public static void main(String[] args) {
/* get input */
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
frequency = inputFrequency(frequency,input);
System.out.println(frequency);
scanner.close();
nodesPQ = createNodes(nodesPQ, frequency);
node a = nodesPQ.poll();
node b = nodesPQ.poll();
node OGroot = new node(a,b,a.getFrequency() + b.getFrequency(),null);
node finalRoot = createBranch(nodesPQ,OGroot);
finalRoot.inorderPrint();
}
/* counts occurrences of letters in output returns Map<Char, # of occurrences> */
public static Map<Character,Integer> inputFrequency(Map<Character,Integer> map,String input){
/* split input into char Array */
char[] charsArray = input.toCharArray();
/* fill hashmap ['Char', # of occurrences] */
for(char i : charsArray) {
int count = 0;
for(char j : charsArray){
if(i == j) {
count++;
}
map.put(i,count);
}
}
return map;
}
/* take Map of <Character, # of occurrences> and create nodes inside PQ*/
public static PriorityQueue<node> createNodes(PriorityQueue<node> nodePQ,Map<Character,Integer> map){
nodePQ = new PriorityQueue<>();
// create nodes inside PQ
for (Map.Entry<Character,Integer> i : frequency.entrySet()) {
Character character = i.getKey();
Integer occurrences = i.getValue();
node n = new node(null,null,occurrences,character);
nodePQ.add(n);
}
return nodePQ;
}
public static node createBranch(PriorityQueue<node> nodePQ, node root){
node newRoot = null;
for(node i : nodePQ) {
node nextFrequent = nodePQ.poll();
root = huffmanHelper(nodesPQ,root,nextFrequent);
}
return newRoot;
}
public static node huffmanHelper(PriorityQueue<node> nodePQ, node root, node nextFrequent){
node newRoot = new node(nextFrequent,root,root.getFrequency() + nextFrequent.getFrequency(),null);
//get next letter and frequency
return newRoot;
}
}
我的堆栈跟踪:
hello my name is sam
{ =4, a=2, s=2, e=2, h=1, y=1, i=1, l=2, m=3, n=1, o=1}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.PriorityQueue$Itr.next(PriorityQueue.java:536)
at huffman.huffman.createBranch(huffman.java:83) - is the start of
forLoop in createBranch
at huffman.huffman.main(huffman.java:26) - is node finalRoot =
createBranch(nodesPQ,OGroot); in main
此行从优先级队列中删除一个元素:
node nextFrequent = nodePQ.poll();
它发生在遍历相同优先级队列的循环中,因此算作禁止的并发修改。这会导致您的异常。
is there a better way you can think of iterating over a PriorityQueue to remove items? just a regular for loop w PQ.size() ?
如果想按优先级排完队列,一直取出元素直到poll()
returns null
(代码未测试):
node nextFrequent = nodePQ.poll();
while (nextFrequent != null) {
// Do something with nextFrequent
nextFrequent = nodePQ.poll();
}
poll
方法 检索并移除此队列的头部,或者 returns null
如果此队列为空。
文档 link:Queue.poll()