带有自定义AddAll方法的Java ArrayList

时间:2016-10-18 17:28:39

标签: java android arraylist

我有一个名为News的自定义类,每个新闻都有一个独特的id

public class News{ 
    public long id;
    public String title;
    //...
}

现在我想为我的ArrayList

使用自定义dataset

这是我的自定义ArrayList

public class NewsArrayList<E> extends ArrayList<News> {
    @Override
    public boolean addAll(Collection<? extends News> c) {
        ArrayList<News> b = new ArrayList<>();
        boolean notExists;
        for (News n : c) {
            notExists = true;
            for (News ex : this) {
                if (n.id == ex.id) {
                    notExists = false;
                    break;
                }
            }
            if (notExists)
                b.add(n);
        }
        return super.addAll(b);
    }
}

如果我使用这样的类:

ArrayList<News> myNews = mDatabase.getNewsByOffset(5,10); // will return first 5 News from database
NewsArrayList<News> mDataset = new NewsArrayList<>();
mDataset.addAll(myNews);
myNews = mDatabase.getNewsByOffset(4,10); // will return first 4 News from database
mDataset.addAll(myNews);

那么此代码是否安全且优化为News中没有重复的mDataset项?

还有另外一个简单的问题,这个break;,只打破了所有for-loop或内部问题?

....
for (News n : c) {
    notExists = true;
    for (News ex : this) {
        if (n.id == ex.id) {
            notExists = false;
            break;
        }
    }
    if (notExists)
        b.add(n);
}
....

2 个答案:

答案 0 :(得分:2)

如果您想要一个没有重复的集合,请考虑使用Set,如果您想使用LinkedHashSet来保持订单,则只需覆盖方法equals和您班hashCode中的News

例如:

@Override
public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || this.getClass() != o.getClass()) return false;

    final News news = (News) o;

    return this.id == news.id;

}

@Override
public int hashCode() {
    return (int) (this.id ^ this.id >>> 32);
}

您的代码将是:

ArrayList<News> myNews = mDatabase.getNewsByOffset(5,10); // will return first 5 News from database
Set<News> mDataset = new LinkedHashSet<>(myNews);
myNews = mDatabase.getNewsByOffset(4,10); // will return first 4 News from database
mDataset.addAll(myNews);

但是,如果您确实需要使用List而不重复,则仍可继续下一步:

List<News> mDataset = new ArrayList<>(new LinkedHashSet<>(myNews));
  

只是另一个快速问题,这个突破;,打破所有for循环   还是内在的?

它打破内部循环只打破所有for循环使用标签作为下一个:

main: for (News n : c) {
    ...
    for (News ex : this) {
        if (n.id == ex.id) {
            ...
            // Break the loop with the label main
            break main;
        }
    }
    ...
}

答案 1 :(得分:0)

这种方法可行,但不是实现这一目标的最直接或最有效的方法。

通常,如果您希望确保集合中只有一个特定项目的副本,那么您将使用设置而不是列表。套装会自动确保您不会有任何重复。

为了让Set正确检测并避免存储重复项,您需要在News类中实现 equals() hashCode()方法,以便它知道何时考虑两个新闻实例&#34;相同&#34;。在您的情况下,看起来您只需要参考&#34; id&#34;为了唯一地标识每个新闻项目。您的IDE可能会自动生成equals()/ hashCode()方法 - 这是一个常见功能。

要使用的最常见的Set实现是 HashSet 。使用HashSet和您的方法之间的主要区别在于HashSet不会按照添加它们的顺序为您提供项目。这可能不是问题。如果是,您可以使用 LinkedHashSet 代替