-2

Let's assume I'm given a map represented as {[A, 0], [B, 1] [C, 2], [D, 3], [E, 4], [F, 5], [G, 6]} and were to delete one of its elements, i.e [E, 4], then my new map would become {[A, 0], [B, 1] [C, 2], [D, 3], [F, 5], [G, 6]}. How would I resize or shrink this map such that the elements whose index is greater than the index of the deleted element, would decrement (shrink) their index (Value) by one, like this {[A, 0], [B, 1] [C, 2], [D, 3], [F, 4], [G, 5]}? In addition to this, how would I adjust the size of ArrayList<ArrayList<GraphEdge<L>>> matrix?

Note: The assignment of the index to the nodes must follow the order of insertion, therefore the first node inserted in the graph must have assigned the index 0, the second the index 1 and so on.

The Java code:

@Override
public void removeNode(GraphNode<L> node) {
    if (node == null) {
        throw new NullPointerException();
    }
    if (!this.nodesIndex.containsKey(node)) {
        throw new IllegalArgumentException();
    }

   // Implement here

}

@Override
public boolean addNode(GraphNode<L> node) {
    if (node == null) {
        throw new NullPointerException();
    }
    if (this.nodesIndex.containsKey(node)) {
        return false;
    }

   // Implement here

}

The map which contains its elements (Keys) associated to their indexes (Values) is represented as following:

/* 
 * A set of nodes in which every node is associated to its index in the adjacency 
 * matrix
 */
protected Map<GraphNode<L>, Integer> nodesIndex = new HashMap<GraphNode<L>, Integer>();

Whereas the matrix is represented like this:

/*
 * The adjacency matrix in which its elements are null or objects of the class 
 * GraphEdge<L>. The use of ArrayList allows the matrix to resize 
 * gradually whenever a new object (element) is added or removed 
 * (deleted).
 */
protected ArrayList<ArrayList<GraphEdge<L>>> matrix = new ArrayList<ArrayList<GraphEdge<L>>>();
  • 4
    *the elements that come after the deleted element*. What do you mean by that? Maps aren't ordered. Are you sure you're using the right data structure? – shmosel Dec 23 '21 at 22:05
  • @shmosel The elements when added to the map, follow the insertion order. The first element has index 0, the second has index 1 and so on. – Albin Sopaj Dec 23 '21 at 22:17
  • @AlbinSopaj, ordering in _HashMap_ [is not guaranteed](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html) _in particular, it does not guarantee that the order will remain constant over time_ and definitely the order does not depend on the integer values stored as values. – Nowhere Man Dec 24 '21 at 12:31

2 Answers2

2

You should not be using a Map for your purpose. The value part of a map’s entry pairing has nothing to do with the entry’s position within the map. Indeed, entries have no position within a Map!

If you want to track objects by a zero based index into the collection, use a List. Every list tracks additions by such an index.

List< Car > favoriteCars = new ArrayList<>(4) ;
favoriteCars.add( subaruBrz ) ;
favoriteCars.add( hondaElement ) ;
favoriteCars.add( jeepRenegade ) ;
favoriteCars.add( kiaSoul ) ;

Get second favorite car.

Car secondFavoriteCar = favoriteCars.get( 1 ) ;  // hondaElement.

But then we realize the Honda Element is no longer manufactured. So drop from our list.

favoriteCars.remove( hondaElement ) ; 

The index positions of the remaining elements move up to close the gap. Asking for second favorite car will now show the jeepRenegade object.

Car secondFavoriteCar = favoriteCars.get( 1 ) ;  // jeepRenegade. 
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • There is an appropriate typer of map- a LinkedHashMap – Gabe Sechan Dec 23 '21 at 22:23
  • @GabeSechan There are also `NavigableSet` and `SortedSet` implementations with an order. But when used as a `Map`, none of those can be assumed to have an order. Furthermore, deleting from a `LinkedHashMsp` does not alter the paired value in the rest of the entries as required for this question. – Basil Bourque Dec 23 '21 at 22:34
0

Use a LinkedHashMap. LinkedHashMap are maps that also keep insertion order by instead of hashing the value, hashing a node in a linked list of values. You could then iterate over all keys in the map until you find the matching key and alter all values after that in the iteration.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • 2
    This is really not a good approach. The OP should use a List implementation. Then when an element at index N is removed. The elements after it will now be shifted down and their indices updated by -1 which is what the OP wanted. – WJS Dec 23 '21 at 22:50
  • @WJS Depends on your requirements. If you need O(1) lookuptime with an ordered component, such as an LRU cache, this is the correct implementation. If you don't need O(n) search, then you use a list. But there is a definite subset of algorithms where you should be using LinkedHashMap. And it looks like his requirements is for O(1) search. – Gabe Sechan Dec 25 '21 at 03:59