我写代码来抓取网站上的所有信息。我想在过滤并保存到数据库时,过滤的数据不包含数据库。如果包含数据库,我不想保存它(“因为它重复”)。我在下面写代码:
@Data
@Entity
public class PostFeedItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "link_profile")
private String linkProfile;
@Column(name = "link_image")
private String linkImage;
@Column(name = "full_name")
private String fullName;
@Column(name = "content_title")
private String contentTitle;
@Column(name = "time_published")
private String timePublished;
@Column(name = "number_view")
private String numberView;
@Column(name = "number_comment")
private String numberComment;
@Column(name = "number_clip")
private String numberClip;
@Column(name = "point")
private String points;
@ElementCollection
@CollectionTable(name = "tags", joinColumns = @JoinColumn(name = "tag_id"))
@Column(name = "tags_post")
private List<String> tags = new ArrayList<>();
}
现在我使用方法
从数据库中获取所有数据public Iterable<PostFeedItem> findAllPostFeedItemInDatabase() {
return postFeedItemRepository.findAll();
}
我有一个列表listPostFieldItems,我想与postFeedItemInDatabase进行比较。如果listPostFieldItems中的任何元素与postFeedItemInDatabase中的任何元素匹配,则我不想保存它。如果不匹配,我保存它。我在下面写代码:
List<PostFeedItem> postFeedItemInDatabase = (List<PostFeedItem>) findAllPostFeedItemInDatabase();
if(!postFeedItemInDatabase.isEmpty()) {
for (int i = 0; i < listPostFieldItems.size(); i++) {
for (int j = i+1; j < postFeedItemInDatabase.size(); j++) {
if((listPostFieldItems.get(i).getContentTitle().equals(postFeedItemInDatabase.get(j).getContentTitle()))) {
postFeedItemRepository.save(listPostFieldItems.get(i));
}
}
}
} else {
listPostFieldItems.forEach(postFeedItem -> {
postFeedItemRepository.save(postFeedItem);
});
}
但是没有用。我有个问题。如果List<PostFeedItem> listPostFieldItems
中的任何元素都不匹配List<PostFeedItem> listItemFromDatabase
,如何比较listPostFieldItems
与listPostFieldItems
和保存listPostFieldItems
中的所有对象。
答案 0 :(得分:2)
您的代码是错误的,因为它应该使用索引j
,并且应该以不同的方式构建循环,这是您的匹配项,因此,保存数据库中的现有记录需要相反的操作。
有更简单的方法,因为两者都是我建议先保留contentTitle
的列表,因为这是查找匹配/不匹配的关键
List<String> allTitles = postFeedItemInDatabase.stream().map(PostFeedItem::getContentTitle).collect(Collectors.toList());
那么你可以
从数据库标题列表中作为标题的第一个列表中删除匹配项:
listPostFieldItems.removeIf(elt -> allTitles.contains(elt.contentTitle));
listPostFieldItems.forEach(postFeedItem -> postFeedItemRepository.save(postFeedItem));
或者,保留不匹配的内容
listPostFieldItems = listPostFieldItems.stream().filter(elt -> !allTitles.contains(elt.contentTitle)).collect(Collectors.toList());
listPostFieldItems.forEach(postFeedItem -> postFeedItemRepository.save(postFeedItem));
执行操作
listPostFieldItems.stream()
.filter(elt -> !allTitles.contains(elt.contentTitle))
.forEach(postFeedItem -> postFeedItemRepository.save(postFeedItem));
答案 1 :(得分:0)
1)将列表转换为java.util.concurrent.CopyOnWriteArrayList; 2)迭代您的清单; 3)如果任何元素不匹配,则将对象添加到列表中。
答案 2 :(得分:0)
我认为您的源代码有2个问题
For循环postFeedItemInDatabase
必须从0开始而不是i + 1。
如果条件listPostFieldItems.get(i).getContentTitle().equals(postFeedItemInDatabase.get(i).getContentTitle())
看起来很奇怪。
not equals
。如果listPostFieldItems
中的项目不等于postFeedItemInDatabase
-> save()中的项目。postFeedItemInDatabase.get(j)
而非postFeedItemInDatabase.get(i)
答案 3 :(得分:0)
返回(list1.size()== list2.size())&& list1.containsAll(list2);需要一种比较列表中对象的方法。