简体   繁体   English

Java - HashSet 的对象数组

[英]Java - Array of Objects to HashSet

I've got following array:我有以下数组:

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

The Optreden object constructor looks like this: Optreden object 构造函数如下所示:

Optreden(name, stage, hour, minutes, rating);

Now, I have to create a HashSet of the Optreden objects BUT it may not contain duplicate names, so when I print the HashSet it has to look like this:现在,我必须创建一个 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)--> *****

Thing is, I can't edit the Optreden class and it only has a constructor and a toString method, no getName() getter.问题是,我无法编辑 Optreden class,它只有一个构造函数和一个 toString 方法,没有 getName() getter。

How can I pull this off?我怎样才能做到这一点? Thanks.谢谢。

Does it have to be a HashSet?它必须是HashSet吗? If you're happy to use a TreeSet instead, create one with a custom comparator that compares the names.如果您乐于改用 TreeSet,请使用自定义比较器创建一个用于比较名称的比较器。 Something like (not compiled or tested:):类似的东西(未编译或测试:):

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

As long as Optreden is not a final class, you can subclass it to trap name in the constructor and implement equals() and hashcode() to use name , as follows:只要Optreden不是final的 class,您可以将其子类化以在构造函数中捕获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();
    }
}

As long as you are using only instances of this class in your set, it will work.只要您在您的集合中仅使用此 class 的实例,它就可以工作。

You will have to override setName() , if it exists, to update name .您必须覆盖setName() (如果存在)以更新name

Please see my comment.请看我的评论。 Under the current restrictions given in the original question ie only a constructor and a toString() method available, you could create a set, using an ordered Set (eg TreeSet) and a custom Comparator implementation.在原始问题中给出的当前限制下,即只有一个构造函数和一个 toString() 方法可用,您可以使用有序集合(例如 TreeSet)和自定义Comparator器实现来创建一个集合。 Your Comparator implementation will then use the only accessor method Optreden.toString() to parse the name of the group.然后,您的 Comparator 实现将使用唯一的访问器方法Optreden.toString()来解析组的名称。 eg例如

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

You can then create a TreeSet(new OptredenComparator) and add your instances of Optreden to it.然后,您可以创建一个TreeSet(new OptredenComparator)并将您的 Optreden 实例添加到其中。

I would like to emphasize that although this is the answer to the original question, the root issue that need to be addressed is the design of the class being used as data container (Optreden)我想强调的是,虽然这是对原始问题的答案,但需要解决的根本问题是用作数据容器的 class 的设计(Optreden)

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM