有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将两个集合添加到一起,如果存在则合并,如果不存在则添加

当将两个电视节目相加时,假设它们是同一个节目,如果电视节目one有一个季节1,而电视节目two有一个季节1,它不会将电视节目1中的episodes季节1合并到电视节目one中的1季节,因为它认为它们是相等的。然而,这个问题是,如果我也在equals函数中添加了第四季的剧集,那么TVShow one将包含两个条目,都是第1季,而不是将两个剧集合并为一个

TreeSet是正确的收藏吗
我该怎么做呢

public class TVShow extends Show implements Iterable<Season> {
    private final TreeSet<Season> seasons;
}

public class Season implements Iterable<Episode>, Comparable<Season> {
    private final TreeSet<Episode> episodes;
    private String name = null;
    private int number;

    @Override
    public boolean equals(Object o) {
        if (o == this)
            return true;
        else if (!(o instanceof Season))
            return false;
        else {
            Season other = (Season) o;
            return this.number == other.number;
        }
    }
}

public class Episode implements Comparable<Episode> {
    private String name;
    private int number;
}

例如:

TVShow one = new TVShow();
Season s1 = new Season(1);
s1.add(new Episode(1));
one.add(s1);

TVShow two = new TVShow();
Season sOne = new Season(1);
sOne.add(new Episode(1));
sOne.add(new Episode(2));
sOne.add(new Episode(3));
two.add(sOne);

one.add(two);

结果: 第一季{1,集{1,2,3}}


共 (1) 个答案

  1. # 1 楼答案

    合并两个季节非常简单,因为episodes字段是一个Set,您只需调用addAll(),任何重复项都会被忽略

    合并两个节目更复杂,因为当发现重复的季节时,它们需要合并,所以你不能只调用^{,因为这将添加新的季节,但不会合并现有的季节

    问题是TreeSet没有一种方法可以通过number获得现有的季节。解决这个问题的一种方法是将Set更改为Map,由number键控。这将是推荐的方法,但是有一个技巧,使用subSet()first()Set中获取“等于”正在查找的对象的对象

    因此,为了完成代码,消除name字段和Iterable接口,因为它们对问题无关紧要,我们得到:

    final class TVShow {
        private final TreeSet<Season> seasons = new TreeSet<>();
    
        public TVShow(Season... seasons) {
            this.seasons.addAll(Arrays.asList(seasons));
        }
        public void merge(TVShow that) {
            for (Season season : that.seasons) {
                // Add if season is new, otherwise merge it
                if (! this.seasons.add(season)) {
                    this.seasons.subSet(season, true, season, true)
                                .first().merge(season);
                }
            }
        }
        @Override
        public String toString() {
            return this.seasons.toString();
        }
    }
    
    final class Season implements Comparable<Season> {
        private final int number;
        private final TreeSet<Episode> episodes = new TreeSet<>();
    
        public Season(int number, Episode... episodes) {
            this.number = number;
            this.episodes.addAll(Arrays.asList(episodes));
        }
        @Override
        public int compareTo(Season that) {
            return Integer.compare(this.number, that.number);
        }
        public void merge(Season that) {
            // Just add missing episodes
            this.episodes.addAll(that.episodes);
        }
        @Override
        public String toString() {
            return this.number + ": " + this.episodes;
        }
    }
    
    final class Episode implements Comparable<Episode> {
        private final int number;
    
        public Episode(int number) {
            this.number = number;
        }
        @Override
        public int compareTo(Episode that) {
            return Integer.compare(this.number, that.number);
        }
        @Override
        public String toString() {
            return String.valueOf(this.number);
        }
    }
    

    测试

    TVShow show1 = new TVShow(
            new Season(1, new Episode(1), new Episode(2), new Episode(3)),
            new Season(2, new Episode(1), new Episode(2), new Episode(3)));
    TVShow show2 = new TVShow(
            new Season(1, new Episode(2), new Episode(4), new Episode(6)),
            new Season(3, new Episode(1), new Episode(2), new Episode(4)));
    System.out.println("show1: " + show1);
    System.out.println("show2: " + show2);
    System.out.println();
    
    show1.merge(show2);
    System.out.println("show1: " + show1);
    System.out.println("show2: " + show2);
    

    输出

    show1: [1: [1, 2, 3], 2: [1, 2, 3]]
    show2: [1: [2, 4, 6], 3: [1, 2, 4]]
    
    show1: [1: [1, 2, 3, 4, 6], 2: [1, 2, 3], 3: [1, 2, 4]]
    show2: [1: [2, 4, 6], 3: [1, 2, 4]]
    

    输出显示show2未被修改,在show1中,第1季被合并,第3季被添加


    更新:使用Map替代Set的替代版本<推荐

    final class TVShow {
        private final TreeMap<Integer, Season> seasons = new TreeMap<>();
    
        public TVShow(Season... seasons) {
            for (Season season : seasons)
                this.seasons.put(season.getNumber(), season);
        }
        public TVShow merge(TVShow that) {
            for (Season season : that.seasons.values())
                this.seasons.merge(season.getNumber(), season, Season::merge);
            return this;
        }
        @Override
        public String toString() {
            return this.seasons.values().toString();
        }
    }
    
    final class Season {
        private final int number;
        private final TreeMap<Integer, Episode> episodes = new TreeMap<>();
    
        public Season(int number, Episode... episodes) {
            this.number = number;
            for (Episode episode : episodes)
                this.episodes.put(episode.getNumber(), episode);
        }
        public int getNumber() {
            return this.number;
        }
        public Season merge(Season that) {
            for (Episode episode : that.episodes.values())
                this.episodes.merge(episode.getNumber(), episode, Episode::merge);
            return this;
        }
        @Override
        public String toString() {
            return this.number + ": " + this.episodes.values();
        }
    }
    
    final class Episode {
        private final int number;
    
        public Episode(int number) {
            this.number = number;
        }
        public int getNumber() {
            return this.number;
        }
        public Episode merge(Episode that) {
            // Nothing to merge
            return this;
        }
        @Override
        public String toString() {
            return String.valueOf(this.number);
        }
    }