How to remove not equals Objects using ArrayList in Java

做~自己de王妃 提交于 2021-01-29 08:22:06

问题


If I have an ArrayList of books and I want to delete a certain number of books only if they are different (using equals). How can I approach the problem?

For example, if I have 3 different books and my quantitytoremove is 3.. then those 3 books have to be deleted. Assuming quantitytoremove can't be higher than the number of DIFFERENT books inside the array.

I tried something like this but I know there are issues with what I wrote. Is there a function available with streams or else that can help me?


   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;

                }

            } 
        }
    }

回答1:


First, @Override equals() in class Foo to decide what's the attributes that make two objects equals and remove using recursion

Explain how recursion works

qn represents how many removes are done

Starting point i = 0 j = 1 and recursion till the base condition reached

Step 1, Base condition: if i or j exceeded the size of the array or qn exceeded the quantityToRemove return qn

Step 2, Check equality if array elements of i and j not equal then remove and increment qn and decrement j to avoid missing element

Step 3 for all i and increment j Repeat to Step 3 till reaching the base condition

Step 4 increment ++i

Step 5 start new recursion with increment i and start j from i+1

After the recussion has finished, check if qn not exceeded the quantityToRemove and remove from the array if contains 1 book. this for a case when you have different 4 books and want all of them to be removed

...

Trace

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;
    }

, output

[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]

, And for this input

        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);

, output

[]



回答2:


Use Java Stream and 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);




回答3:


Steps to be followed:

  1. Put bookList into a Set to remove the duplicate elements and then create a List, books out of the Set.
  2. Add quantityToRemove elements from books to another List, toBeRemovedList.
  3. Add all elements, except one item each also belonging to tobeRemovedList from bookList to another List, toBeReturnedList.

Note: You can replace the first step using Stream API as shown below:

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;
}

Demo:

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;
    }
}

Output:

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

Result for removeDifferent(books, 2):

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

Result for removeDifferent(books, 1):

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


来源:https://stackoverflow.com/questions/61646691/how-to-remove-not-equals-objects-using-arraylist-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!