【问题标题】:Is there a better way to remove multiples items and shift index from an ArrayList in Java 8有没有更好的方法从 Java 8 中的 ArrayList 中删除多个项目并移动索引
【发布时间】: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&lt;Integer, Book&gt;?我的意思是为什么Book 类中需要索引?

标签: java arraylist java-8


【解决方案1】:

我过去做过类似的事情。如果您使用 LinkedList 并以相反的数字顺序处理要删除的索引,则在处理列表时索引不会更改。

indexes.stream()
        .sorted(Comparator.reverseOrder())
        .forEach(bookShelf.getBooks()::remove));

【讨论】:

    【解决方案2】:

    晚上好!如果我正确理解您的目标,我会使用带有 .remove(index) 的数组列表。将此示例插入您的 IDE,看看它是否符合您的要求:

       public static void main(String[] args) {
        ArrayList<String> books = new ArrayList<>();
    
        //This just puts stuff in the array
        for(int i = 0; i < 100; i++){
            books.add("Book " + Integer.toString(i));
        }
    
        //This is just for display
        Consumer<ArrayList<String>> displayBookShelf = (ArrayList<String> data) -> {
            for(int i = 0; i < data.size(); i++){
                System.out.println("Position " + i + ": " + data.get(i));
            }
            System.out.println("\n\n");
        };
    
        displayBookShelf.accept(books);
    
        //Remove first element
        books.remove(0);
    
        displayBookShelf.accept(books);
    
        //Remove the third element
        books.remove(2);
    
        displayBookShelf.accept(books);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 2019-07-10
      • 2012-01-16
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      相关资源
      最近更新 更多