【问题标题】:How to remove not equals Objects using ArrayList in Java如何在 Java 中使用 ArrayList 删除不等于对象
【发布时间】:2020-05-06 22:42:10
【问题描述】:

如果我有一个 ArrayList 书籍,并且我想删除一定数量的书籍,前提是它们不同(使用 equals)。我该如何解决这个问题?

例如,如果我有 3 本书,而我的 quantitytoremove 是 3.. 那么这 3 本书必须被删除。假设quantitytoremove 不能高于数组中不同书籍的数量。

我尝试过这样的事情,但我知道我写的内容存在问题。是否有可用于流的功能或其他可以帮助我的功能?


   public Basket removeDifferent(int quantitytoremove) {
        int removed=0;

        for (int i = 0; i < this.numberBooks && removed<quantitytoremove ; i++) {
            for (int j = i+1; j < this.numberBooks && removed<quantitytoremove; j++) {
                if (!(this.BooksArray.get(i).equals(this.BooksArray.get(j)))) {

                    Book Book_i= this.BooksArray.get(i);
                    Book Book_j= this.BooksArray.get(j);
                    this.BooksArray.remove(Book_i);
                    this.BooksArray.remove(Book_j);

                    removed=removed+2;
                    this.numberBooks=numberBooks-2;
                    i=0;j=1;

                }

            } 
        }
    }

【问题讨论】:

  • 改用Set
  • @MadProgrammer 我需要将其保留为 ArrayList,这可以使用 Set 吗?
  • 好吧,您可以使用ArrayList,将其通过Set,这将只保留对象的非静态实例,然后将其放回ArrayList ...所以是的
  • 请注意,您应遵循 Java 命名约定:变量名称和方法名称应以驼峰命名。
  • @MadProgrammer 使用 Set 适合这个操作的函数是什么?

标签: java algorithm


【解决方案1】:

使用Java Stream和removeIf:

List<Book> books = new ArrayList<>();
// init the books
List<Book> distinctBooks = books.stream().distinct().collect(Collectors.toList());
int quantitytoremove = 3;
List<Book> needToDeleted = new ArrayList<>();
for (int i = 0; i < quantitytoremove; i++) {
    needToDeleted.add(distinctBooks.get(i));
}

books.removeIf(needToDeleted::contains);
System.out.println(books);

【讨论】:

    【解决方案2】:

    应遵循的步骤:

    1. bookList 放入Set 以删除重复元素,然后在Set 之外创建Listbooks
    2. quantityToRemove元素从books添加到另一个ListtoBeRemovedList
    3. bookList到另一个ListtoBeReturnedList,添加所有元素,除了一个项目也属于tobeRemovedList

    注意:您可以使用Stream API 替换第一步,如下所示:

    static List<Book> removeDifferent(List<Book> bookList, int quantityToRemove) {
        // Put `bookList` into a Set to remove the duplicate elements and then create
        // a List, `books` out of the Set
        List<Book> books = new ArrayList<Book>(new HashSet<Book>(bookList));
    
        // You can replace the above code with Stream code given below:
        // List<Book> books = bookList.stream().distinct().collect(Collectors.toList());
    
        // Add `quantityToRemove` elements from `books` to another List,
        // `toBeRemovedList`
        List<Book> toBeRemovedList = new ArrayList<Book>();
        for (int i = 0; i < quantityToRemove; i++) {
            toBeRemovedList.add(books.get(i));
        }
    
        // Add all elements, except one item each also belonging to `tobeRemovedList`
        // from `bookList` to another List, `toBeReturnedList`
        List<Book> toBeReturnedList = new ArrayList<Book>();
        int c = 0;// Counter
        for (Book book : toBeRemovedList) {
            for (int i = c; i < bookList.size(); i++) {
                if (book.equals(bookList.get(i))) {
                    c = i;
                    break;
                }
                toBeReturnedList.add(bookList.get(i));
            }
            c++;
        }
        for (int i = c; i < bookList.size(); i++) {
            toBeReturnedList.add(bookList.get(i));
        }
    
        // Return toBeReturnedList
        return toBeReturnedList;
    }
    

    演示:

    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Objects;
    
    class Book {
        int id;
    
        public Book(int id) {
            this.id = id;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(id);
        }
    
        @Override
        public boolean equals(Object obj) {
            Book other = (Book) obj;
            return this.id == other.id;
        }
    
        @Override
        public String toString() {
            return "Book [id=" + id + "]";
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            List<Book> books = new ArrayList<Book>();
            books.add(new Book(1));
            books.add(new Book(1));
            books.add(new Book(1));
            books.add(new Book(2));
            books.add(new Book(3));
    
            List<Book> updatedList = removeDifferent(books, 3);
    
            // Display updated list
            updatedList.stream().forEach(System.out::println);
        }
    
        static List<Book> removeDifferent(List<Book> bookList, int quantityToRemove) {
            // Put `bookList` into a Set to remove the duplicate elements and then create
            // a List, `books` out of the Set
            List<Book> books = new ArrayList<Book>(new HashSet<Book>(bookList));
    
            // You can replace the above code with Stream code given below:
            // List<Book> books = bookList.stream().distinct().collect(Collectors.toList());
    
            // Add `quantityToRemove` elements from `books` to another List,
            // `toBeRemovedList`
            List<Book> toBeRemovedList = new ArrayList<Book>();
            for (int i = 0; i < quantityToRemove; i++) {
                toBeRemovedList.add(books.get(i));
            }
    
            // Add all elements, except one item each also belonging to `tobeRemovedList`
            // from `bookList` to another List, `toBeReturnedList`
            List<Book> toBeReturnedList = new ArrayList<Book>();
            int c = 0;// Counter
            for (Book book : toBeRemovedList) {
                for (int i = c; i < bookList.size(); i++) {
                    if (book.equals(bookList.get(i))) {
                        c = i;
                        break;
                    }
                    toBeReturnedList.add(bookList.get(i));
                }
                c++;
            }
            for (int i = c; i < bookList.size(); i++) {
                toBeReturnedList.add(bookList.get(i));
            }
    
            // Return toBeReturnedList
            return toBeReturnedList;
        }
    }
    

    输出:

    Book [id=1]
    Book [id=1]
    

    removeDifferent(books, 2) 的结果:

    Book [id=1]
    Book [id=1]
    Book [id=3]
    

    removeDifferent(books, 1) 的结果:

    Book [id=1]
    Book [id=1]
    Book [id=2]
    Book [id=3]
    

    【讨论】:

    • 如果我有 3 本书并且我的要删除的数量是 3,这将不起作用
    • 例如,如果我有 3 本书,我要删除的数量是 3.. 那么这 3 本书必须被删除。
    • 取决于要删除的数量,如果数量要删除= 3,则应删除3
    • @Hazel - 在检查了您对 Ecto [@Ecto yeah exactly, one instance of each book ] 的最后回复后,我再次更新了答案。希望它符合您的要求。
    • @Hazel - 我已经用演示程序的输出更新了我的答案。我还提到了更多测试的输出,它们是removeDifferent(books, 2)removeDifferent(books, 1)。据我了解要求,测试结果满足他们。但是,在您测试并批准之前,我会假设它还没有完成。
    【解决方案3】:

    首先,Foo 类中的@Override equals() 来决定使用recursion 使两个对象相等和删除的属性是什么

    解释递归的工作原理

    qn 表示完成了多少次删除

    起点 i = 0 j = 1 并递归直到达到基本条件

    第 1 步,基本条件:如果 ij 超出数组大小或 qn 超出 quantityToRemove 则返回 qn

    第2步,检查相等性如果ij的数组元素不相等,则删除并增加qn并减少j以避免丢失元素

    第 3 步为所有 i 增加 j 重复第 3 步直到达到基本条件

    第四步递增++i

    第 5 步以增量 i 开始新的递归,并从 i+1 开始 j

    recussion 完成后,检查 qn 是否没有超过 quantityToRemove,如果包含 1 本书,则从数组中删除。这适用于您有不同的 4 本书并希望将它们全部删除的情况

    ...

    追踪

    i = 0, j = 1, 2, ...., N

    i = 1, j = 2, 3, ...., N

    i = 2, j = 3, 4, ...., N

    i = 3, j = 4, 5, ...., N

    ...

       static class Book {
            int id;
            String title;
    
            public Book(int id, String title) {
                this.id = id;
                this.title = title;
            }
    
            @Override
            public boolean equals(Object obj) {
                Book other = (Book) obj;
                return this.title.equals(other.title);
            }
    
            @Override
            public String toString() {
                return id + ": " + title;
            }
        }
    
        public static void main(String[] a) {
            Book b1 = new Book(1, "b1");
            Book b2 = new Book(2, "b2");
            Book b3 = new Book(3, "b3");
            Book b4 = new Book(4, "b4");
            Book b5 = new Book(1, "b1");
            List<Book> list = new ArrayList<>();
            list.add(b1);
            list.add(b2);
            list.add(b3);
            list.add(b4);
            list.add(b5);
            list.add(new Book(1, "b1"));
            list.add(new Book(1, "b1"));
            list.add(new Book(1, "b1"));
    
            System.out.println(list);
            removeDifferent(list, 2);
            System.out.println(list);
        }
    
        static void removeDifferent(List<Book> booksArray, int quantityToRemove) {
            int qn = removeDifferent(booksArray, quantityToRemove, 0, 0, 1);
            if (booksArray.size() == 1 && qn < quantityToRemove)
                booksArray.remove(0);
        }
    
        static int removeDifferent(List<Book> booksArray, int quantityToRemove, int qn, int i, int j) {
            if (i >= booksArray.size() || j >= booksArray.size() || qn >= quantityToRemove)
                return qn;
            if (!booksArray.get(i).equals(booksArray.get(j))) {
                booksArray.remove(j);
                j--;
                qn++;
            }
            qn = removeDifferent(booksArray, quantityToRemove, qn, i, 1 + j);
            ++i;
            qn = removeDifferent(booksArray, quantityToRemove, qn, i, i + 1);
            return qn;
        }
    

    ,输出

    [1: b1, 2: b2, 3: b3, 4: b4, 1: b1, 1: b1, 1: b1, 1: b1]
    [1: b1, 4: b4, 1: b1, 1: b1, 1: b1, 1: b1]
    

    ,对于这个输入

            Book b1 = new Book(1, "b1");
            Book b2 = new Book(2, "b2");
            Book b3 = new Book(3, "b3");
            Book b4 = new Book(4, "b4");
            List<Book> list = new ArrayList<>();
            list.add(b1);
            list.add(b2);
            list.add(b3);
            list.add(b4);
            System.out.println(list);
            removeDifferent(list, 4);
            System.out.println(list);
    

    ,输出

    []
    

    【讨论】:

    • 如果有 book1 book2 和 book3 怎么办,& quantityToRemove=3。我想会有一个没有被删除吗?
    • 如果它们不同,yes 将被删除
    • 我试过了,没有,如果你的清单包含 3 本书,我打电话给 removeDifferent(list, 3);将有 1 本书未删除
    • 你试过递归解决方案了吗?
    • 似乎工作 :) 但它让我真的头晕谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 2010-11-21
    • 2016-04-11
    • 2020-08-23
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多