java - 如何从多个列表中创建匹配对象列表并删除匹配列表中的对象,使其反映在原始列表中
问题描述
很抱歉,如果有人问过这个问题,但我在谷歌搜索中找不到类似的东西,所以就到这里。假设我有两个对象
笔记本
public class NoteBook {
private String name;
private String description;
public NoteBook(String name, String description) {
this.name = name;
this.description = description;
}
}
和笔记
public class Note {
private String sourceNoteBook
private String name;
private String category;
private String details;
public Note(String sourceNoteBook,String name, String category, String details) {
this.sourceNoteBook = sourceNoteBook;
this.name = name;
this.category = category;
this.details = details;
}
}
在程序中,用户可以创建多个 NoteBook 对象,每个 NoteBook 存储可变数量的 Notes。最终我想添加一个搜索功能,可以按类别或名称搜索笔记并返回找到的笔记列表。
通常我会使用 2 个 For 循环来遍历笔记本列表,然后遍历每个笔记本的笔记列表并比较字符串。像这样的东西:
For (NoteBook noteBook: noteBooks) {
For(Note note :noteBooks.getNoteList){
if (note.getCategory().contains(someString)) {
matchingNotes.add(notes);
}
}
}
但是,我现在希望能够从 matchingNotes 列表中删除笔记,这样原始笔记本中的笔记也会被删除。
什么是存储和搜索这两个类的最佳方法,以便我可以实现这样的功能。
编辑:
只是为了澄清,最终结果是我希望用户能够在所有笔记本中搜索笔记类别,然后程序将返回与该类别匹配的笔记列表。然后他/她可以从该列表中删除一条笔记,这样它也可以在原始笔记本中删除。例如完全从程序中删除。
解决方案
迭代器:
可能是最简单的解决方案。而且由于 java 在foreach
循环中使用迭代器,因此性能是相同的。
For (NoteBook noteBook: noteBooks) {
Iterator<Note> it = noteBooks.getNoteList().iterator();
while (it.hasNext()) {
Note note = it.next();
if (note.getCategory().equals(someString)) {
it.remove();
}
}
}
SQL:
这将是最佳的。然而,即使使用轻量级的东西,例如 H2 或 SQLite,也需要重构。而且在非常轻量级的应用程序中也不是一个选项。
高效:
如果您只按类别或名称搜索,您可以使用 2 个地图:
Map<String, Note> notesByCategory;
Map<String, Note> notesBytName
这将需要O(n)
内存来存储地图,但会O(1)
及时进行非常有效的查找(与当前的O(n)相比)。我会避免这种解决方案,因为很容易在笔记内容和地图之间实现不一致的状态。
编辑:
var newNoteNames = newList.stream().map(Note::getName).collect(Collectors.toSet());
var oldNoteNames = noteBooks.stream().flatMap(Notebook::getNodeList).map(Note::getName).collect(Collectors.toSet());
var removedNames = oldNoteNames.removeAll(newNoteNames);
for (var removedName : removedNames) {
for (NoteBook noteBook: noteBooks) {
Iterator<Note> it = noteBooks.getNoteList().iterator();
while (it.hasNext()) {
Note note = it.next();
if (note.getName().contains(removedName)) {
it.remove();
}
}
}
}
推荐阅读
- javascript - 如何在不创建新文件的情况下继续在 fs 中写入文件?
- spring - @Query 选择不加入
- html - 停用单个 SVG 路径 - HTML
- sphinx - 什么是具有 net_idle 状态的 sphinx 线程?
- json - 如何使用 jsonpb 将 JSON 解组为包含 oneof 定义的 protobuf?
- php - 向浏览器显示实时 shell 信息
- angular - 带有接口的Angular 6服务
- azure - 如何使用 Azure FileTrigger 监视目录
- laravel - Laravel Eloquent Caching 分页聚合计数结果
- mysql - 通过shell将mysql数据库结构复制到另一个数据库不起作用