Java 匿名添加对象时,从 ArrayList 获取特定对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18456192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get specific objects from ArrayList when objects were added anonymously?
提问by leigero
I have created a short example of my problem. I'm creating a list of objects anonymously and adding them to an ArrayList
. Once items are in the ArrayList
I later come back and add more information to each object within the list. Is there a way to extract a specific object from the list if you do not know its index?
我为我的问题创建了一个简短的例子。我正在匿名创建一个对象列表并将它们添加到ArrayList
. 一旦项目在ArrayList
我稍后回来并向列表中的每个对象添加更多信息。如果您不知道它的索引,有没有办法从列表中提取特定对象?
I know only the Object's 'name' but you cannot do a list.get(ObjectName)
or anything. What is the recommended way to handle this? I'd rather not have to iterate through the entire list every time I want to retrieve one specific object.
我只知道对象的“名称”,但你不能做 alist.get(ObjectName)
或任何事情。处理此问题的推荐方法是什么?我宁愿不必每次要检索一个特定对象时都遍历整个列表。
public class TestCode{
public static void main (String args []) {
Cave cave = new Cave();
// Loop adds several Parties to the cave's party list
cave.parties.add(new Party("FirstParty")); // all anonymously added
cave.parties.add(new Party("SecondParty"));
cave.parties.add(new Party("ThirdParty"));
// How do I go about setting the 'index' value of SecondParty for example?
}
}
class Cave {
ArrayList<Party> parties = new ArrayList<Party>();
}
class Party extends CaveElement{
int index;
public Party(String n){
name = n;
}
// getter and setter methods
public String toString () {
return name;
}
}
class CaveElement {
String name = "";
int index = 0;
public String toString () {
return name + "" + index;
}
}
采纳答案by MadProgrammer
Given the use of List
, there's no way to "lookup" a value without iterating through it...
鉴于使用List
,没有办法“查找”一个值而不遍历它......
For example...
例如...
Cave cave = new Cave();
// Loop adds several Parties to the cave's party list
cave.parties.add(new Party("FirstParty")); // all anonymously added
cave.parties.add(new Party("SecondParty"));
cave.parties.add(new Party("ThirdParty"));
for (Party p : cave.parties) {
if (p.name.equals("SecondParty") {
p.index = ...;
break;
}
}
Now, this will take time. If the element you are looking for is at the end of the list, you will have to iterate to the end of the list before you find a match.
现在,这需要时间。如果您要查找的元素位于列表的末尾,则必须遍历到列表的末尾才能找到匹配项。
It might be better to use a Map
of some kind...
使用Map
某种形式可能会更好......
So, if we update Cave
to look like...
所以,如果我们更新Cave
看起来像......
class Cave {
Map<String, Party> parties = new HashMap<String, Party>(25);
}
We could do something like...
我们可以做类似...
Cave cave = new Cave();
// Loop adds several Parties to the cave's party list
cave.parties.put("FirstParty", new Party("FirstParty")); // all anonymously added
cave.parties.put("SecondParty", new Party("SecondParty"));
cave.parties.put("ThirdParty", new Party("ThirdParty"));
if (cave.parties.containsKey("SecondParty")) {
cave.parties.get("SecondParty").index = ...
}
Instead...
反而...
Ultimately, this will all depend on what it is you want to achieve...
最终,这一切都取决于您想要实现的目标......
回答by Makoto
List.indexOf()
will give you what you want, provided you know precisely what you're after, and provided that the equals()
method for Party
is well-defined.
List.indexOf()
会给你你想要的,只要你确切地知道你想要什么,并且equals()
方法Party
是明确定义的。
Party searchCandidate = new Party("FirstParty");
int index = cave.parties.indexOf(searchCandidate);
This is where it gets interesting - subclasses shouldn't be examining the private properties of their parents, so we'll define equals()
in the superclass.
这就是有趣的地方——子类不应该检查其父类的私有属性,因此我们将equals()
在超类中定义。
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CaveElement)) {
return false;
}
CaveElement that = (CaveElement) o;
if (index != that.index) {
return false;
}
if (name != null ? !name.equals(that.name) : that.name != null) {
return false;
}
return true;
}
It's also wise to override hashCode
if you override equals
- the general contract for hashCode
mandates that, if x.equals(y)
, then x.hashCode() == y.hashCode().
hashCode
如果您覆盖,则覆盖也是明智的equals
-hashCode
强制的一般合同,如果x.equals(y)
,则x.hashCode() == y.hashCode()。
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + index;
return result;
}
回答by Karthik T
If you want to lookup objects based on their String
name, this is a textbook case for a Map
, say a HashMap
. You could use a LinkedHashMap
and convert it to a List
or Array
later (Chris has covered this nicely in the comments below).
如果您想根据String
名称查找对象,这是 a 的教科书案例Map
,例如 a HashMap
。您可以使用 aLinkedHashMap
并将其转换为 aList
或Array
更高版本(克里斯在下面的评论中很好地介绍了这一点)。
LinkedHashMap
because it lets you access the elements in the order you insert them if you want to do so. Otherwise HashMap
or TreeMap
will do.
LinkedHashMap
因为如果您愿意,它可以让您按照插入的顺序访问元素。否则HashMap
还是TreeMap
会做。
You could get this to work with List
as the others are suggesting, but that feels Hacky to me.. and this will be cleaner both in short and long run.
你可以List
像其他人建议的那样使用它,但这对我来说感觉很糟糕……从短期和长期来看,这都会更干净。
If you MUST use a list for the object, you could still store a Map
of the object name to the index in the array. This is a bit uglier, but you get almost the same performance as a plain Map
.
如果您必须为对象使用列表,您仍然可以Map
将对象名称的a 存储到数组中的索引。这有点难看,但您获得的性能几乎与普通Map
.
回答by Josh M
I would suggest overriding the equals(Object)
of your Party
class. It might look something like this:
我建议覆盖equals(Object)
你的Party
班级。它可能看起来像这样:
public boolean equals(Object o){
if(o == null)
return false;
if(o instanceof String)
return name.equalsIgnoreCase((String)o);
else if(o instanceof Party)
return equals(((Party)o).name);
return false;
}
After you do that, you could use the indexOf(Object)
method to retrieve the index of the party specified by its name, as shown below:
完成后,您可以使用该indexOf(Object)
方法检索其名称指定的派对的索引,如下所示:
int index = cave.parties.indexOf("SecondParty");
Would return the index of the Party
with the name SecondParty
.
将返回的索引Party
的名称SecondParty
。
Note: This only works because you are overriding the equals(Object)
method.
注意:这仅在您覆盖该equals(Object)
方法时才有效。
回答by StormeHawke
You could use list.indexOf(Object)
bug in all honesty what you're describing sounds like you'd be better off using a Map
.
你可以list.indexOf(Object)
诚实地使用bug,你所描述的听起来像你最好使用Map
.
Try this:
尝试这个:
Map<String, Object> mapOfObjects = new HashMap<String, Object>();
mapOfObjects.put("objectName", object);
Then later when you want to retrieve the object, use
然后当你想检索对象时,使用
mapOfObjects.get("objectName");
Assuming you do know the object's name as you stated, this will be both cleaner and will have faster performance besides, particularly if the map contains large numbers of objects.
假设您确实如您所说的那样知道对象的名称,这将更清晰,而且性能会更快,尤其是在地图包含大量对象的情况下。
If you need the objects in the Map
to stay in order, you can use
如果您需要中的对象Map
保持有序,您可以使用
Map<String, Object> mapOfObjects = new LinkedHashMap<String, Object>();
instead
反而
回答by saurav
As per your question requirement , I would like to suggest that Map will solve your problem very efficient and without any hassle.
根据您的问题要求,我想建议 Map 将非常有效地解决您的问题,并且没有任何麻烦。
In Map you can give the name as key and your original object as value.
在 Map 中,您可以将名称指定为键,将原始对象指定为值。
Map<String,Cave> myMap=new HashMap<String,Cave>();
回答by user2608389
You could simply create a method to get the object by it's name.
您可以简单地创建一个方法来按名称获取对象。
public Party getPartyByName(String name) {
for(Party party : parties) {
if(name.equalsIgnoreCase(party.name)) {
return party;
}
}
return null;
}