Java 在附加值上返回索引的ArrayList
我正在寻找一种类似于ArrayList的java数据结构,当我只使用一个值参数进行添加或推送时,会自动为我返回一个索引 例如:Java 在附加值上返回索引的ArrayList,java,data-structures,collections,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
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周围编写一个包装器吗?这似乎很简单,可以在某个地方开箱即用
编辑:
对于这个用例,我需要索引(键)是固定的和唯一的。有人建议画一张地图,我同意这一点。有人知道在值插入中自动(唯一)生成键的映射实现吗?我只是想决定是否需要实现自己的包装器。元素将添加到列表的末尾。因此,您可以使用
elements.size()-1
获取新元素索引
请注意,如果多个线程同时修改列表,这将无法可靠地工作
编辑:还请注意,使用ArrayList
s索引作为唯一ID可能不是一个好主意,因为元素索引可能会更改(例如,当您使用add(int,Object)
删除元素或插入新元素时)。如果这是一个问题,则取决于您想对索引执行什么操作:如果您在添加元素后只需要它一小段时间,并且可以确保列表在此期间没有被修改,那么就没有问题。在另一种情况下,即使是在调用add(Object)
时返回索引的方法也没有帮助,因为无论如何索引都不会得到更新。要防止此问题,您可以:
- 确保从不从列表中删除元素,也从不使用
添加元素add(int,Object)
- 除了删除元素,您还可以使用方法
将它们设置为set(int,null)
。这样,任何元素索引都不会更改null
- 使用其他一些数据结构,例如一个带有自定义ID的地图,如helloannalil在其答案中建议的那样
- 如果元素的最大数量不太大,可以使用
,元素索引表示ID。如上所述,要删除元素,可以将其设置为ArrayList
,以便不更改索引。插入时,可以重用具有null
值的位置null
- 您还可以使用此答案中显示的两种方法之一:(关键字
或AtomicLong
)IdentityHashMap
- 不要依赖于
或Object.hashCode()
的“唯一性”,因为这是不可靠的(请运行本部分底部的示例进行尝试)System.identityHashCode(Object)
String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;
String thing=“theThing”;
List strList=new ArrayList();
添加(事物);
int indexOfThing=strList.size()-1;
我的意思是,这比实现自己的列表更容易,而且很有效 如果你真的想要这个功能,你可以使用map而不是list基于你的评论和编辑的问题,我想你可以像这样扩展一个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;
}
}
private MyMap<String> map = new MyMap<String>();
.....
.....
String element = "foo";
String elementTwo = "bar";
int index1 = map.add(element);
int index2 = map.add(elementTwo);
String elem1 = map.get(index1); // will return "foo"
String elem2 = map.get(index2); // will return "bar"
然后将元素添加到MyMap
,如下所示:
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;
}
}
private MyMap<String> map = new MyMap<String>();
.....
.....
String element = "foo";
String elementTwo = "bar";
int index1 = map.add(element);
int index2 = map.add(elementTwo);
String elem1 = map.get(index1); // will return "foo"
String elem2 = map.get(index2); // will return "bar"
现在您有了index1
和index2
作为插入字符串的索引,可以在应用程序的生命周期中使用或传递这些字符串。您可以在MyMap
中插入或删除任意次数的元素,但索引(index1
和index2
)将返回插入的元素,如下所示:
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;
}
}
private MyMap<String> map = new MyMap<String>();
.....
.....
String element = "foo";
String elementTwo = "bar";
int index1 = map.add(element);
int index2 = map.add(elementTwo);
String elem1 = map.get(index1); // will return "foo"
String elem2 = map.get(index2); // will return "bar"
String thing=“theThing”;
List strList=new ArrayList();
添加(事物);
int indexOfThing=strList.size()-1;
如果删除项目,则此操作将不再有效。
int index1=elements.add(element).size()-1
;这不管用吗int index1=elements.size()有什么问题;元素。添加(元素)代码>?我很困惑。为什么写第二行来获取当前长度会如此糟糕???如果使用该大小,是否总是保证获得唯一的ID?如果在添加之间删除一个元素会发生什么?@RyanR。我更新了我的答案以涵盖这个问题。谢谢你的答案(+1)。我们将检查一个答案,其中包含有关map实现或缺少map实现的更多详细信息。@RyanR。我添加了一些实现想法和注释…我喜欢这项研究。我主持了HashClash课程。有趣的是,在那里看到了独特性的突破。我的系统中没有100亿次试验,但很高兴知道。尽管@anubhava也有一些很好的输入,我还是会给你检查一下(由于背景研究)。@RyanR。谢谢:-)我知道这种独特性不能保证,但我不知道打破它有多“容易”…是的,他有一些优点。没有他我可能不会做这项研究,所以也谢谢你,阿努巴瓦;-)回答得不错(+1),这属于我问题的“实现我自己的包装器”部分。如果没有其他人能想出一个更“标准库”的方法,我会在支票上拖延一段时间,但最终会给你。好奇这是否是实现这一点的最明智的方式?如果您知道有一组有界的元素,那么最好围绕一个固定大小的数组编写这类内容?是的,这属于您问题的实现我自己的包装器部分。IMO使用任何基于数组或集合的实现都需要更多的代码,因为您将从该存储中添加/删除元素。@RyanR。请注意,根据的Javadocs,这并不能保证有效,JVM不需要为不同的obj返回不同的哈希代码