【发布时间】:2019-11-16 23:56:07
【问题描述】:
我有一个不允许超过 100 本书的书架。我想删除位于特定索引处的图书,并在删除一本书后更新图书索引。
Example:
Book0 -> Index 0
Book1 -> Index 1
Book2 -> Index 2
当我删除 Book1 时,Book2 的更新索引应该为 1。
我不确定这里用什么:
- ArrayList 是 LinkedList 还是简单的 Array 是最佳选择吗? (我需要从特定索引中删除)
这是我的代码:
public class Book {
private int id;
private String title;
private int writerId;
private int index;
// getters & setters
}
public class BookShelf {
private UUID id;
private String name;
private List<Book> books;
private int nrOfBooks;
}
我建立了一个书架。它必须少于 100 本书
class BookShelfBuild {
public static BookShelf createBookShelf() {
BookShelf booKShelf = new BookShelf();
booKShelf.setId(UUID.randomUUID());
booKShelf.setName("Awesome books for kids");
booKShelf.setBooks(getBooks());
booKShelf.setNrOfBooks(booKShelf.getBooks().size());
return booKShelf;
}
private static List<Book> getBooks() {
List<Book> booksList = new ArrayList<>();
Random randomGenerator = new Random();
for (int i = 0; i < 78; i++) {
Book book = new Book();
book.setId(randomGenerator.nextInt(10000));
book.setIndex(i);
book.setWriterId(randomGenerator.nextInt(10000));
book.setTitle("Book no: " + randomGenerator.nextInt(10000));
booksList.add(book);
}
return booksList;
}
}
最后,我检查索引是否有效。我唯一不能做的就是更新书的索引属性。
public static void main(String[] args) {
BookShelf bookShelf = BookShelfBuild.createBookShelf();
List<Integer> indexesToRemove = Arrays.asList(1);
List<Book> books = removeBooks(bookShelf, indexesToRemove);
System.out.println(books);
}
public static List<Book> removeBooks(BookShelf bookShelf, List<Integer> indexes) {
List<Book> toBeRemoved = new ArrayList<>();
indexes.stream()
.filter(index -> isValidIndex(bookShelf.getBooks(), index))
.forEach(index -> {
toBeRemoved.add(bookShelf.getBooks().get(index));
});
bookShelf.getBooks().removeAll(toBeRemoved);
return bookShelf.getBooks();
}
public static boolean isValidIndex(List<?> list, int index) {
return index >= 0 && index < list.size();
}
【问题讨论】:
-
根据列表的使用方式选择列表类型。如果要以永久随机访问方式使用,则
ArrayList将是合适的。如果您要添加和插入大量项目,LinkedList可能会更好。在后一种情况下,您仍然需要遍历列表以确定要添加或删除项目的时间点。使用Deque将允许搜索从列表的开头或结尾开始,具体取决于相关索引的相对位置。 -
您可能需要考虑使用某种
SortedSet实现(如TreeSet),因为您可能希望通过id订购书籍,并且插入的时间复杂度也很高/删除和搜索。因为如果您考虑一下,书籍应该是唯一存储的(并且您有一个id字段,这意味着每本书都是唯一的 id)并且一旦您听到唯一一词,这意味着您应该使用 @ 开始您的解决方案987654332@ -
除了您共享的代码。潜在的意图是更新 Book 对象的
index字段而其他对象被删除?还是只是它们在存储中要更新的集合中的实际索引?另一个疑问,你为什么不使用nrOfBooks来检查索引是否有效。 -
嗨,naman,是的,我的第一个目标是找到一种更好的方法来流式传输书籍列表和索引列表,并在一个管道中进行删除。我的第二个目标确实是更新索引字段..因为删除一个项目后,这些索引字段需要转变
-
您当前的代码并没有真正显示您正在谈论的第二个目标,并且字段
index应该对应于集合中图书的索引还是只是减少了?另外:如果查找取决于书的index,为什么不从书架内的书列表中创建Map<Integer, Book>?我的意思是为什么Book类中需要索引?