Skip to content

getAllPresent can return null values #176

@ipnm

Description

@ipnm

Looks like using Iterator.remove before Entry.setValue is not correct. remove can substitute some TreeNodes in HashMap to plain Nodes, while iterator continues to iterate over old TreeNode instances and sets the values to those garbage nodes.

public class Main {
    static class Key {
        @Override
        public int hashCode() {
            return 0; // to put keys in one bucket
        }
    }
    public static void main(String[] args) {
        List<Key> keys = new ArrayList<>();
        for (int i = 0; i < 11; ++i) { // 11 is big enough for a map to use tree nodes
            keys.add(new Key());
        }
        Map<Object, Object> data = Collections.singletonMap(keys.get(10), 1);

        Map<Object, Object> result = new HashMap<>();
        for (Object key : keys) {
            result.put(key, null);
        }

        for (Iterator<Map.Entry<Object, Object>> iter = result.entrySet().iterator(); iter.hasNext();) {
            Map.Entry<Object, Object> entry = iter.next();
            Object value = data.get(entry.getKey());
            if (value == null) {
                iter.remove();
            } else {
                entry.setValue(value); // this call doesn't set the value
            }
        }

        if (result.containsValue(null)) {
            System.out.println("FAILED");
        } else {
            System.out.println("OK");
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions