Java 匿名添加对象时从ArrayList获取特定对象?

Java 匿名添加对象时从ArrayList获取特定对象?,java,object,arraylist,Java,Object,Arraylist,我已经为我的问题创建了一个简短的示例。我正在匿名创建一个对象列表,并将它们添加到ArrayList。一旦项目位于ArrayList中,我稍后会返回并向列表中的每个对象添加更多信息。如果您不知道某个特定对象的索引,是否有方法从列表中提取该对象 我只知道对象的“名称”,但您不能执行列表。get(ObjectName)或任何操作。建议的处理方法是什么?我不希望每次检索一个特定对象时都要遍历整个列表 public class TestCode{ public static void main

我已经为我的问题创建了一个简短的示例。我正在匿名创建一个对象列表,并将它们添加到
ArrayList
。一旦项目位于
ArrayList
中,我稍后会返回并向列表中的每个对象添加更多信息。如果您不知道某个特定对象的索引,是否有方法从列表中提取该对象

我只知道对象的“名称”,但您不能执行
列表。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;
    }
}
公共类测试代码{
公共静态void main(字符串参数[]){
洞穴=新洞穴();
//循环将多个参与方添加到洞穴的参与方列表中
cave.parties.add(新的一方(“第一方”);//所有匿名添加
添加(新一方(“第二方”);
添加(新一方(“第三方”);
//例如,如何设置SecondParty的“索引”值?
}
}
类洞{
ArrayList parties=新的ArrayList();
}
类方扩展了CaveElement{
整数指数;
公众党(字符串n){
name=n;
}
//getter和setter方法
公共字符串toString(){
返回名称;
}
}
类空穴元素{
字符串名称=”;
int指数=0;
公共字符串toString(){
返回名称+“”+索引;
}
}
将为您提供所需,前提是您准确地知道自己的目标,并且
equals()
方法定义良好。

Party searchCandidate = new Party("FirstParty");
int index = cave.parties.indexOf(searchCandidate);
这就是有趣的地方——子类不应该检查其父类的私有属性,因此我们将在超类中定义
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;
}
如果覆盖
hashCode
,那么覆盖
hashCode
也是明智的做法。
hashCode
的总合同规定,如果
x.equals(y)
,那么


如果要根据对象的
字符串
名称查找对象,这是
映射
的教科书案例,例如
哈希映射
。您可以使用a,稍后将其转换为
列表
数组
(Chris在下面的评论中很好地介绍了这一点)

LinkedHashMap
,因为它允许您按照插入元素的顺序访问元素(如果需要)。否则,
HashMap
TreeMap
就可以了

你可以像其他人所建议的那样,用
List
来处理这个问题,但我觉得这有点不对劲。。从短期和长期来看,这将更加清洁


如果必须为对象使用列表,则仍然可以将对象名称的
映射到数组中的索引。这有点难看,但您获得的性能几乎与普通的
Map

相同。我建议您覆盖
Party
类的
equals(Object)
。它可能看起来像这样:

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;
}
完成此操作后,可以使用
indexOf(Object)
方法检索由其名称指定的参与方的索引,如下所示:

int index = cave.parties.indexOf("SecondParty");
将返回名为
第二方的
参与方
的索引


注意:这只适用于重写
equals(Object)
方法。

您可以使用
list.indexOf(Object)
bug老实说,您描述的内容听起来像是最好使用
映射

试试这个:

Map<String, Object> mapOfObjects = new HashMap<String, Object>();
mapOfObjects.put("objectName", object);
假设您确实知道如您所述的对象的名称,这将更干净,而且性能也会更快,尤其是当地图包含大量对象时

如果需要
贴图中的对象保持有序,可以使用

Map<String, Object> mapOfObjects = new LinkedHashMap<String, Object>();
Map-mapoobjects=newlinkedhashmap();

相反

由于使用了
列表
,如果不迭代,就无法“查找”一个值

例如

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;
    }
}
现在,这需要时间。如果要查找的元素位于列表的末尾,则必须迭代到列表的末尾才能找到匹配项

最好使用某种类型的
地图

所以,如果我们把洞穴更新成

class Cave {
    Map<String, Party> parties = new HashMap<String, Party>(25);
}
相反


最终,这将取决于您想要实现什么…

根据您的问题要求,我想建议Map将非常高效且无任何麻烦地解决您的问题

在地图中,您可以将名称作为键,将原始对象作为值

  Map<String,Cave> myMap=new HashMap<String,Cave>();
Map myMap=newhashmap();

您只需创建一个方法,通过名称获取对象

public Party getPartyByName(String name) {
    for(Party party : parties) {
        if(name.equalsIgnoreCase(party.name)) {
            return party;
        }
    }
    return null;
}

您必须使用列表吗?特别是,您可以始终使用
map.values().toArray(新参与方[0])
将其转储到数组中,也可以使用
newArrayList(map.values())
将其转储到列表中。在目前为止的5或6个答案中,我最喜欢您的一个。它有O(1)查找,并且仍然保持插入顺序。@ChrisJester Young是的,谢谢,这就是为什么我建议
LinkedHashMap
,我应该明确指出,我只能接受一个答案,我也喜欢这个答案。不幸的是,由于我的项目的性质,我被列表困住了,所以我选择了另一个答案。“你仍然可以得到一张赞成票。”莱杰罗:好的,你接受对你有意义的东西。谢谢你的+1。最后,一定要考虑一下我建议的混合解决方案。我还建议它违反了
等于
合同,但这只是MHO:P@MadProgrammer呃,这似乎很方便:可能很方便,但是如果有两个
Party
对象命名相同,但索引不同,会发生什么呢。合同现在被打破了;)没错,从来没有考虑过:(我相信这是最有用的回答。我将无法使用地图,这场混乱还有一点
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 = ...
}
  Map<String,Cave> myMap=new HashMap<String,Cave>();
public Party getPartyByName(String name) {
    for(Party party : parties) {
        if(name.equalsIgnoreCase(party.name)) {
            return party;
        }
    }
    return null;
}