ArrayList,返回索引,添加值

时间:2012-04-25 03:38:47

标签: java data-structures collections

我正在寻找一个类似于ArrayList的java数据结构,当我只使用一个值参数进行添加或推送时,将自动为我返回一个索引。

例如:

ArrayList<String> elements = new ArrayList<String>();

String element = "foo";
String elementTwo = "bar";

int index1 = elements.add(element); //note this does not exist, i.e. returns bool in api
int index2 = elements.add(elementTwo);

System.out.println(elements.get(index1)); //would give "foo"

我可以看到围绕ArrayList编写一个包装器类来管理一个计数器,该计数器在每次添加操作时都会递增并调用:

ArrayList.add(int index, E element)

你真的需要为此编写一个围绕ArrayList的包装器吗?这似乎很简单,可以在某个地方开箱即用?

修改

我需要为此用例修复和唯一索引(键)。提出了一张地图,我同意这一点。有没有人知道一个地图实现,它会在值插入上为您提供自动(唯一)生成的键?我只是想确定是否需要为此实现自己的包装器。

5 个答案:

答案 0 :(得分:5)

该元素将添加到列表的末尾。因此,您可以使用elements.size()-1来获取新元素索引。

请注意,如果多个线程同时修改列表,这将无法正常工作。

编辑:另请注意,使用ArrayList索引作为唯一ID可能不是一个好主意,因为元素索引可能会更改(例如,当您删除元素时)或使用add(int, Object))插入新的。如果这是一个问题,取决于你想要对索引做什么:如果你只需要在添加元素后短时间内需要它,并且可以确保在此期间不修改列表,则没有问题。在另一种情况下,即使是在调用add(Object)时返回索引的方法也无济于事,因为无论如何索引都没有得到更新。要防止出现此问题,您可以:

  • 请确保您永远不会从列表中删除元素,也不会使用add(int, Object)添加元素。
  • 您可以使用方法null将其设置为set(int, null),而不是删除元素。这样,没有元素索引会改变。
  • 使用其他一些数据结构,例如带有自定义ID的地图,例如helloannalil在他的回答中建议。

编辑2:我没有找到合适的,准备好使用的实现(但这并不意味着没有,当然)。为了提出一个好的解决方案,需要有关数据结构预期用途的更多信息,但这里有一些想法和注意事项:

  • 如果元素的最大数量不大,则可以使用ArrayList,元素index表示ID。如上所述,要删除元素,可以将其设置为null,以便不更改索引。插入时,可以重复使用null值的位置。
  • 您还可以使用此答案中显示的两种方法之一:https://stackoverflow.com/a/8939049/1347968(关键字AtomicLongIdentityHashMap
  • 取决于Object.hashCode()System.identityHashCode(Object)的“唯一性”,因为无法保证(通过运行{{3}底部的示例来尝试})。

答案 1 :(得分:2)

我在那种情况下做的事情(我喜欢ArrayLists)是通过询问列表的大小来获取最后一个索引:

String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;

我的意思是,比实现自己的List更容易,只是工作。

答案 2 :(得分:2)

如果你真的想要这个功能,可以使用map而不是list

答案 3 :(得分:2)

根据您的评论和编辑过的问题,我认为您可以扩展HashMap供您使用,如下所示:

public class MyMap<V> extends HashMap<Integer, V> {
    private static final long serialVersionUID = 1L;
    public int add(V elem) {
        int key = System.identityHashCode(elem);
        super.put(key, elem);
        return key;
    }
}

然后在你的课堂内声明MyMap,如下所示:

private MyMap<String> map = new MyMap<String>();

然后将您的元素添加到MyMap,如下所示:

.....
.....
String element = "foo";
String elementTwo = "bar";
int index1 = map.add(element);
int index2 = map.add(elementTwo);

现在您有index1index2作为插入字符串的索引,您可以在应用程序的生命周期中使用或传递这些字符串。您可以在MyMap中多次插入或删除元素,但索引(index1index2)会返回您插入的元素,如下所示:

String elem1 = map.get(index1); // will return "foo"
String elem2 = map.get(index2); // will return "bar"

答案 4 :(得分:0)

String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;

如果您删除某个项目,则该功能将不再有效。