0
graph = {1:{'a','b'},2:{'c','d'},3:{'e','f'},4:{'g','h'},5:{'b','d'},6:{'b','e'},7:{'a','c'},8:{'f','h'},9:{'e','g'}}

What I have done:

public class Try {
    public static void main(String[] args) {
        Set<Character> universal = new HashSet<>();
        Collections.addAll(universal, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h');
        // System.out.println(universal);
        HashMap<Integer, HashSet<Character>> graph =
                new HashMap<Integer, HashSet<Character>>();
        HashSet<Character> values = new HashSet<Character>();
        Collections.addAll(values, 'a', 'b');

        System.out.println(values);
        // Output : [a, b]

        graph.put(1, values);
        System.out.println(graph.get(1));
        // Output : [a, b]

        System.out.println(graph);
        // Output : {1=[a, b]}

        values.removeAll(values);
        System.out.println(graph.get(1));
        // Output : []

        // Why did the value clear out from the graph?
        System.out.println(graph);
        // Output : {1=[]}
    }
}

How do I put these values at once instead of using put() function all the time? Isn't there a better way? Also, explain the reason why clear() or remove() function usage on the variable values causes it to be removed from the variable graph. I want the structure to be mutable.

3 Answers3

1

First of all, that doesn't look like a python dictionary. A python dictionary of dictionaries would be

{1: {'a': 'b'}, 2: {'c': 'd'}}

and a dictionary of tuples would be

{1: ('a', 'b'), 2: ('c', 'd')}

In Java, you could express than as a Map<Integer, Map<Character, Character>>, (or maybe a Map<Integer, List<Character>> if that is what you mean) but that leads to non-idiomatic, cumbersome code.

Since your data structure is a map of contiguous integers, a better representation would be an array:

// Using Java 14 record types ...
public record Pair (char first, char second) {}

Pair[] theMapping = new Pair[]{
   null,
   new Pair('a', 'b'),
   new Pair('c', 'd'),
   // etc
};

The only gotcha is the null ... which is needed because Java array indexes start from zero.

This could also be expressed as a char[][] or in other ways that will be easier to use (and more efficient) than a Map of Map formulation.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

The following Python statement:

graph = {1:{'a','b'},2:{'c','d'},3:{'e','f'},4:{'g','h'},5:{'b','d'},6:{'b','e'},7:{'a','c'},8:{'f','h'},9:{'e','g'}}

can be implemented in Java 9+ like this:

graph = Map.of(1, Set.of("a", "b"),
               2, Set.of("c", "d"),
               3, Set.of("e", "f"),
               4, Set.of("g", "h"),
               5, Set.of("b", "d"),
               6, Set.of("b", "e"),
               7, Set.of("a", "c"),
               8, Set.of("f", "h"),
               9, Set.of("e", "g"));

The result is an immutable Map<Integer, Set<String>>, unlike Python, where the result is mutable.

Printed, it looks like this, where order changed because the Map is a HashMap:

{4=[g, h], 3=[e, f], 2=[c, d], 1=[a, b], 9=[e, g], 8=[f, h], 7=[a, c], 6=[b, e], 5=[b, d]}
Andreas
  • 154,647
  • 11
  • 152
  • 247
0

Since Java 9 you can implement it like this, result is modifiable:

Map<Integer, Set<Character>> graph = new HashMap<>(Map.of(
        1, new HashSet<>(Set.of('a', 'b')),
        2, new HashSet<>(Set.of('c', 'd')),
        3, new HashSet<>(Set.of('e', 'f')),
        4, new HashSet<>(Set.of('g', 'h')),
        5, new HashSet<>(Set.of('b', 'd')),
        6, new HashSet<>(Set.of('b', 'e')),
        7, new HashSet<>(Set.of('a', 'c')),
        8, new HashSet<>(Set.of('f', 'h')),
        9, new HashSet<>(Set.of('e', 'g'))));

Shorter statement, but result is unmodifiable:

Map<Integer, Set<Character>> immutable = Map.of(
        1, Set.of('a', 'b'),
        2, Set.of('c', 'd'),
        3, Set.of('e', 'f'),
        4, Set.of('g', 'h'),
        5, Set.of('b', 'd'),
        6, Set.of('b', 'e'),
        7, Set.of('a', 'c'),
        8, Set.of('f', 'h'),
        9, Set.of('e', 'g'));

In earlier versions, since Java 1.5, you can use statements like this, result is modifiable:

Map<Integer, Set<Character>> graph = new HashMap();

graph.put(1, new HashSet(Arrays.asList('a', 'b')));
graph.put(2, new HashSet(Arrays.asList('c', 'd')));
graph.put(3, new HashSet(Arrays.asList('e', 'f')));
graph.put(4, new HashSet(Arrays.asList('g', 'h')));
graph.put(5, new HashSet(Arrays.asList('b', 'd')));
graph.put(6, new HashSet(Arrays.asList('b', 'e')));
graph.put(7, new HashSet(Arrays.asList('a', 'c')));
graph.put(8, new HashSet(Arrays.asList('f', 'h')));
graph.put(9, new HashSet(Arrays.asList('e', 'g')));

Shorter statements, result is also modifiable:

Map<Integer, Set<Character>> graph = new HashMap() {{
    put(1, new HashSet(Arrays.asList('a', 'b')));
    put(2, new HashSet(Arrays.asList('c', 'd')));
    put(3, new HashSet(Arrays.asList('e', 'f')));
    put(4, new HashSet(Arrays.asList('g', 'h')));
    put(5, new HashSet(Arrays.asList('b', 'd')));
    put(6, new HashSet(Arrays.asList('b', 'e')));
    put(7, new HashSet(Arrays.asList('a', 'c')));
    put(8, new HashSet(Arrays.asList('f', 'h')));
    put(9, new HashSet(Arrays.asList('e', 'g')));
}};

See also:
System.arrayCopy() copies object or reference to object?
Invert a Map with redundant values to produce a multimap