Java: ArrayList.clear удаляет элементы из ArrayList, переданные в Map

Я впервые за много лет пишу код Java, и я работаю над сценарием Ghidra, который отображает символы, вызываемые системой, в их вызывающие функции.

private HashMap<Symbol, Reference[]> symbolRefs = new HashMap<Symbol, Reference[]>();
private HashMap<Symbol, List<Function>> callerFuncs = new HashMap<Symbol, List<Function>>();

.
.
.

private void mapSysCallToCallerFunctions(FunctionManager funcMan) throws Exception {
    List<Function> funcs = new ArrayList<Function>();
    for(HashMap.Entry<Symbol, Reference[]> entry: this.symbolRefs.entrySet()) {
        for(Reference ref : entry.getValue()) {
            Function caller = funcMan.getFunctionContaining(ref.getFromAddress());
            if(caller != null) {
                funcs.add(caller);
            }
        }
        this.callerFuncs.put(entry.getKey(), funcs);
        funcs.clear();
    }
}

Моя проблема в том, что я хочу очистить список "funcs", чтобы снова использовать пустой список для следующей итерации. Это приводит к тому, что список функций в моем HashMap тоже по неизвестной причине оказывается пустым. Если я напечатаю здесь свою HashMap:

private void printCallerSymbolMap() throws Exception {
    for(HashMap.Entry<Symbol, List<Function>> entry: this.callerFuncs.entrySet()) {
        printf("Symbol %s:\n", entry.getKey().toString());
        for(Function func : entry.getValue()) {
            printf("Called by function %s\n", func.getName());
        }
    }
}

Я просто получаю вывод:

INFO  Symbol system: (GhidraScript)  
INFO  Symbol system: (GhidraScript) 

Однако, когда я удаляю funcs.clear(), я получаю:

INFO  Symbol system: (GhidraScript)  
INFO  Called by function system (GhidraScript)  
INFO  Called by function system (GhidraScript)  
INFO  Called by function main (GhidraScript)  
INFO  Symbol system: (GhidraScript)  
INFO  Called by function system (GhidraScript)  
INFO  Called by function system (GhidraScript)  
INFO  Called by function main (GhidraScript)  

Хотя должно быть так:

INFO  Symbol system: (GhidraScript)  
INFO  Called by function system (GhidraScript)  
INFO  Called by function system (GhidraScript)  
INFO  Symbol system: (GhidraScript) 
INFO  Called by function main (GhidraScript)  

У меня есть два системных символа, как это думается.

1 ответ

Решение

После очистки списка инициализировать список каждый раз.

private void mapSysCallToCallerFunctions(FunctionManager funcMan) throws Exception {
    List<Function> funcs;
    for(HashMap.Entry<Symbol, Reference[]> entry: this.symbolRefs.entrySet()) {
        funcs = new ArrayList<Function>();
        for(Reference ref : entry.getValue()) {
            Function caller = funcMan.getFunctionContaining(ref.getFromAddress());
            if(caller != null) {
                funcs.add(caller);
            }
        }
        this.callerFuncs.put(entry.getKey(), funcs);
    }
}
Другие вопросы по тегам