Java-哈希集的对象数组

Java-哈希集的对象数组,java,arrays,set,Java,Arrays,Set,我有以下数组: private static Optreden[] optredens = { new Optreden("Editors", "Main Stage", 16, 0, 4), new Optreden("Empire of the Sun", "Pyramid Marquee", 23, 45, 5), new Optreden("Florence and the Machine", "Marquee",

我有以下数组:

private static Optreden[] optredens = {
            new Optreden("Editors", "Main Stage", 16, 0, 4),
            new Optreden("Empire of the Sun", "Pyramid Marquee", 23, 45, 5),
            new Optreden("Florence and the Machine", "Marquee", 18, 45, 3),
            new Optreden("The Specials", "Marquee", 13, 10, 5),
            new Optreden("Muse", "Main Stage", 19, 0, 5),
            new Optreden("Faithless", "Main Stage", 14, 30, 5),
            new Optreden("Absynthe Minded", "Pyramid Marquee", 21, 45, 5),
            new Optreden("Pink", "Main Stage", 20, 30, 2),
            new Optreden("Editors", "Marquee", 21, 20, 4),
            new Optreden("Faithless", "Pyramid Marquee", 19, 0, 5)
            };
Optreden对象构造函数如下所示:

Optreden(name, stage, hour, minutes, rating);
现在,我必须创建Optreden对象的哈希集,但它可能不包含重复的名称,因此当我打印哈希集时,它必须如下所示:

The Specials (Marquee, 13u10)--> *****
Empire of the Sun (Pyramid Marquee, 23u45)--> *****
Florence and the Machine (Marquee, 18u45)--> ***
Pink (Main Stage, 20u30)--> **
Muse (Main Stage, 19u)--> *****
Absynthe Minded (Pyramid Marquee, 21u45)--> *****
Editors (Main Stage, 16u)--> ****
Faithless (Main Stage, 14u30)--> *****
问题是,我无法编辑Optreden类,它只有一个构造函数和一个toString方法,没有getName()getter


我怎样才能做到这一点?谢谢。

只要
Optreden
不是
最终的
类,您就可以在构造函数中将其子类化为trap
name
,并实现
equals()
hashcode()
以使用
name
,如下所示:

public class MyOptreden extends Optreden
{
    private String name;

    public MyOptreden(String name, String stage, int hour, int minutes, int rating) {
        super(name, stage, hour, minutes, rating);
        this.name = name; // A capture name here
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof MyOptreden && ((MyOptreden) obj).name.equals(name);
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}
只要在集合中只使用这个类的实例,它就可以工作


您必须重写
setName()
,如果它存在,要更新
name

,请参阅我的评论。在原始问题中给出的当前限制条件下,即只有构造函数和toString()方法可用,您可以使用有序集(例如TreeSet)和自定义的
比较器
实现创建一个集。然后,您的Comparator实现将使用惟一的访问器方法
Optreden.toString()
来解析组的名称。 e、 g

类OptredenComparator实现Comparator{ ... int比较(Optreden o1,Optreden o2){ //这是为了说明逻辑。注意空值 字符串名称1=o1.split(“”[0]; 字符串名称2=o2.split(“”[0]; 返回name1.compareTo(name2); } ... } 然后,您可以创建一个
TreeSet(新的OptredenComparator)
,并将您的Optreden实例添加到其中

我想强调的是,虽然这是原始问题的答案,但需要解决的根本问题是用作数据容器(Optreden)的类的设计


}

它必须是哈希集吗?如果您愿意使用树集,请创建一个带有自定义比较器的树集,用于比较名称。类似(未编译或测试!):

比较器compareByName=新比较器(){ 公共整数比较(Optreden a、Optreden b){ 返回getName(a).compareTo(getName(b)); } 私有字符串getName(Optreden o){ 字符串s=o.toString(); 返回s.substring(0,(s.indexOf('(')-1); } } 设置optredensUniqueByName=新树集(compareByName); addAll(Arrays.asList(opteredens));
使用名称作为键的映射如何?…最终,哈希集只是一个哈希映射,其键和值是同一个对象。这看起来更像是一个组织问题,而不是技术问题,我们只能帮助您解决技术问题……例如,您可以将Optreden子类化吗?或者如果所有其他方法都失败,反射将忽略可见性以代码可读性、类型安全性和运行时性能为代价。在我看来,您的类Optreden(performance-as-music-in-english)的设计是这个问题的src。一个兼容的javabean设计,包含getter、setter和equals()&hashcode将为您提供足够的帮助。例如,假设您的需求是一个集合,您可以使用带有自定义比较器的TreeSet来实现您的目标。如果您只有一个toString()方法,我将使用字符串构造函数为Optreden创建一个适当的JavaBean。使用它来解析toString()输出设计不当的原始类,并为equals()和hashcode()方法提供正确的实现。Hmmm,Rock Werchter的组织者:DA)您永远不应该在代码中回复
toString()
输出。B)比较器对集合没有用处-您需要equals()。请参阅我的answer@BohemianA)toString()同意。我一开始就警告过这个解决方案,但OP只提供了访问该类的工具。我假设没有访问对象创建位置的权限,否则,为什么不滚动您自己的类?B)关于
比较器
,这是一个有效的选项。请参阅[.@maasg:谢谢。我们的解决方案几乎是一样的——我的可能稍微整洁一点,但你的快了两分钟!
class OptredenComparator implements Comparator<Optreden> {
...

 int compare(Optreden o1, Optreden o2) {
     // this is to illustrate the logic. Mind the nulls
     String name1 = o1.split("(")[0];
     String name2 = o2.split("(")[0];
     return name1.compareTo(name2);
 }
...
}
Comparator<Optreden> compareByName = new Comparator<Optreden>() {
    public int compare(Optreden a, Optreden b) {
        return getName(a).compareTo(getName(b));
    }
    private String getName(Optreden o) {
        String s = o.toString();
        return s.substring(0, (s.indexOf('(') - 1);
    }
}

Set<Optreden> optredensUniqueByName = new TreeSet<Optreden>(compareByName);
optredensUniqueByName.addAll(Arrays.asList(optredens));