开发者

Java - Array of Objects to HashSet

开发者 https://www.devze.com 2023-03-18 21:37 出处:网络
I\'ve got following array: private static Optreden[] optredens = { new Optreden(\"Editors\", \"Main Stage\", 16, 0, 4),

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(name, stage, hour, minutes, rating);

Now, I have to create a HashSet of the Optreden objects BUT it may not cont开发者_开发问答ain duplicate names, so when I print the HashSet it has to look like this:

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.

How can I pull this off? Thanks.


Does it have to be a HashSet? If you're happy to use a TreeSet instead, create one with a custom comparator that compares the names. 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:

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.

You will have to override setName(), if it exists, to update name.


Please see my comment. Under the current restrictions given in the original question i.e. only a constructor and a toString() method available, you could create a set, using an ordered Set (e.g. TreeSet) and a custom Comparator implementation. Your Comparator implementation will then use the only accessor method Optreden.toString() to parse the name of the group. 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);
 }
...
}

You can then create a TreeSet(new OptredenComparator) and add your instances of Optreden to it.

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)

}

0

精彩评论

暂无评论...
验证码 换一张
取 消