How to keep List index fixed in Java
Asked Answered
R

6

6

I want to keep the indices of the items in a Java List fixed.

Example code:

import java.util.ArrayList;
public class Test {
    public static void main(String[] args) {
        ArrayList<Double> a = new ArrayList<Double>();
        a.add(12.3);
        a.add(15.3);
        a.add(17.3);

        a.remove(1);
        System.out.println(a.get(1));
    }
}

This will output 17.3. The problem is that 17.3 was on index 2 and now it's on index 1!

Is there any way to preserve the indices of other elements when removing an element? Or is there another class more suitable for this purpose?

Note: I don't want a fixed size Collection.

Roomette answered 15/12, 2011 at 22:8 Comment(0)
J
5

You might want to use java.util.SortedMap with int keys:

import java.util.*;
public class Test {

    public static void main(String[] args) 
    {
        SortedMap<Integer, Double> a = new TreeMap<Integer, Double>();
        a.put(0, 12.3);
        a.put(1, 15.3);
        a.put(2, 17.3);

        System.out.println(a.get(1)); // prints 15.3
        System.out.println(a.get(2)); // prints 17.3

        a.remove(1);

        System.out.println(a.get(1)); // prints null
        System.out.println(a.get(2)); // prints 17.3
    }
}
  • SortedMap is a variable-size Collection
  • It stores values mapped to an ordered set of keys (similar to List's indices)

No implementation of java.util.List#remove(int) may preserve the indices since the specification reads:

Removes the element at the specified position in this list (optional operation). Shifts any subsequent elements to the left (subtracts one from their indices). Returns the element that was removed from the list.

Jessee answered 15/12, 2011 at 22:26 Comment(1)
And if you don't want to keep track of the next index yourself, you could just subclass SortedMap and add a public V put(V value), and keep track of the next index internally in the subclass.Patrimony
M
5

Instead of calling a.remove(1) you could do a.set(1, null). This will keep all elements in the same place while still "removing" the value at index one.

Menology answered 15/12, 2011 at 22:11 Comment(5)
this way, i should implement a new Type of Lists ,is there any thing standard ?Roomette
The set method is a standard method of the List interface. See docs.oracle.com/javase/6/docs/api/java/util/…Challenge
"set" is ,surely, standard , i mean that i want a Standard Class that use this mechanismRoomette
@MhdSyrwan: there can be no such class because the semantics of List#remove(int) require that an implementation "shifts any subsequent elements to the left".Menology
@Menology well pointed out, I've requested that be added to the accepted answer.Patrimony
J
5

You might want to use java.util.SortedMap with int keys:

import java.util.*;
public class Test {

    public static void main(String[] args) 
    {
        SortedMap<Integer, Double> a = new TreeMap<Integer, Double>();
        a.put(0, 12.3);
        a.put(1, 15.3);
        a.put(2, 17.3);

        System.out.println(a.get(1)); // prints 15.3
        System.out.println(a.get(2)); // prints 17.3

        a.remove(1);

        System.out.println(a.get(1)); // prints null
        System.out.println(a.get(2)); // prints 17.3
    }
}
  • SortedMap is a variable-size Collection
  • It stores values mapped to an ordered set of keys (similar to List's indices)

No implementation of java.util.List#remove(int) may preserve the indices since the specification reads:

Removes the element at the specified position in this list (optional operation). Shifts any subsequent elements to the left (subtracts one from their indices). Returns the element that was removed from the list.

Jessee answered 15/12, 2011 at 22:26 Comment(1)
And if you don't want to keep track of the next index yourself, you could just subclass SortedMap and add a public V put(V value), and keep track of the next index internally in the subclass.Patrimony
A
4

If the relationship should be always the same between the index and value then use a java.util.Map.

Animalist answered 15/12, 2011 at 22:12 Comment(0)
T
2

Instead of removing the element with the call to remove set the element to null:

i.e:

import java.util.ArrayList;
public class Test 
{
    public static void main(String[] args) 
{
        ArrayList<Double> a = new ArrayList<Double>();
        a.add(12.3);
        a.add(15.3);
        a.add(17.3);

        a.set(1, null);
        System.out.println(a.get(1));
    }
}
Tectonic answered 15/12, 2011 at 22:12 Comment(0)
Q
2

You could use a HashMap<Integer, Double>. You could add items using

myMap.put(currentMaximumIndex++, myDoubleValue);

This way, indices would be unique, if you need sparse storage you'd be reasonably okay, and removing a value wouldn't hurt existing ones.

Quitclaim answered 15/12, 2011 at 22:14 Comment(1)
+1. This seems to be the most-space-efficient way of storing the values and not changing the index.Rood
O
1

Addition to the above answer its also suggested you should use LinkedHashMap<Integer,Double>, instead of a regular Hashmap It will preserve the order in which you insert the element.

Olivette answered 3/7, 2014 at 9:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.