Java - HashSet的对象数组

时间:2011-07-09 10:50:12

标签: 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", 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对象的HashSet,但它可能不包含重复的名称,因此当我打印HashSet时,它必须如下所示:

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。

我该如何解决这个问题?感谢。

3 个答案:

答案 0 :(得分:4)

它必须是HashSet吗?如果您乐意使用TreeSet,请使用自定义比较器创建一个比较名称的比较器。像(没有编译或测试!):

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));

答案 1 :(得分:3)

只要Optreden不是final类,您就可以将其子类化为构造函数中的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

答案 2 :(得分:0)

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

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);
 }
...
}

然后,您可以创建TreeSet(new OptredenComparator)并将Optreden的实例添加到其中。

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

}