简体   繁体   English

从Java中的列表中删除项目

[英]Removing items from a list in Java

In my computer science class, we use an online program called CodeHS that gives us assignments that cover certain topics. 在我的计算机科学课上,我们使用一个名为CodeHS的在线程序,它为我们提供了涵盖某些主题的作业。 Usually, I understand ArrayLists relatively well, but this assignment uses Lists instead and it is kind of tripping me up. 通常,我相对较好地理解ArrayLists,但是这个赋值使用了Lists而且它有点让我沮丧。 I have been struggling a little bit and my code (I will link it at the bottom) is returning the exact list that they insert in the method parameters. 我一直在苦苦挣扎,我的代码(我将它们链接在底部)返回它们在方法参数中插入的确切列表。 (in other words, my code is not doing what I want it to. It's not doing anything at all.) I am very new to this and would appreciate some help, with helpful criticism rather than scolding, haha. (换句话说,我的代码没有按照我的意愿行事。它根本没有做任何事情。)我对此很新,并且会感谢一些帮助,有用的批评而不是责骂,哈哈。 Thank you. 谢谢。

Here is the Assignment: 这是作业:

You've been given a list of books to read over the summer, but you need to trim down the list of books so you can finish all of them. 您已经获得了夏季阅读的书籍清单,但您需要减少书籍清单,以便完成所有这些书籍。

Write a method 写一个方法

public List<Book> filterBooks(List<Book> readingList, int maxPages)

That takes a List of Books as a parameter, removes all Books from the readingList that have more than maxPages pages, then returns the resulting list. 这会将Book of Books作为参数,从readingList中删除所有具有多个maxPages页面的Books,然后返回结果列表。

You can access the number of pages of a Book by calling book.getNumPages(). 您可以通过调用book.getNumPages()来访问Book的页数。 The Book class is provided for reference. Book类供参考。

public class Book
{
private String title;
private String author;
private int numPages;

public Book(String theTitle, String theAuthor, int numberOfPages)
{
    title = theTitle;
    author = theAuthor;
    numPages = numberOfPages;
}

public String getTitle()
{
    return title;
}

public String getAuthor()
{
    return author;
}

public int getNumPages()
{
    return numPages;
}

public String toString()
{
    return title + " by " + author;
}

public boolean equals(Book other)
{
    return title.equals(other.title) && author.equals(other.author);
}
}

This is what I have tried: 这是我尝试过的:

public List<Book> filterBooks(List<Book> readingList, int maxPages)
{
Book currentBook;
ArrayList<String> readingList2 = new ArrayList<String>();
for(int i= 0; i < readingList.size(); i++)
{
    currentBook = readingList.get(i);
    if(currentBook.getNumPages() >= maxPages)
    {
       readingList.remove(currentBook);
    }
}

    return readingList;

}

You could use the List.removeIf(...) function, (if it's supported by the list) that does exactly what you want: remove all objects in that list if they meet a criteria. 您可以使用List.removeIf(...)函数(如果列表支持它)完全符合您的要求:如果符合条件,则删除该列表中的所有对象。

So the code would be (with lambda): 所以代码将是(与lambda):

readingList.removeIf(b -> b.getNumPages() <= maxPages);

Or without lambdas: 或者没有lambdas:

readingList.removeIf(new Predicate<Book>() {
    @Override
    public boolean test(Book b) {
        return b.getNumPages() <= maxPages;
    }
}

Your code does not appear to be what you described. 您的代码似乎不是您所描述的。 You should be removing some items from the original list, so it shouldn't return the exact same list, unless none of the books you checked matched the criteria for removal. 您应该从原始列表中删除一些项目,因此它不应返回完全相同的列表,除非您检查的书籍都没有与删除标准相匹配。 (Assuming the list passed in is mutable.) (假设传入的列表是可变的。)

However you also have a couple bugs. 但是你也有一些错误。 Based on the problem description your condition should be > not >=. 根据问题描述,您的条件应该>>>。 You also have a bug in the way you don't compensate for removing from the original list when you address the elements by index. 当您按索引处理元素时,您还有一个错误,就是您无法补偿从原始列表中删除的方式。 If you remove an item at index i you should not increment i because the next book will now be in that position and you don't want to skip it. 如果您删除索引i处的项目,则不应增加i,因为下一本书现在将处于该位置,您不想跳过它。 You will skip some books that you should have eliminated if there are two books in a row that should be removed. 如果连续存在两本应删除的书籍,您将跳过一些应该删除的书籍。

Can you use Java8? 你能用Java8吗? Use lambdas then. 然后使用lambdas。

public List<Book> filterBooks(List<Book> readingList, int maxPages) {
    return readingList.stream().filter(book -> book.getNumPages() <= maxPages).collect(Collectors.toList());
}

If not - never modify the list while you are iterating it. 如果不是 - 在迭代时永远不要修改列表。 Create a new one instead. 改为创建一个新的。

public List<Book> filterBooks(List<Book> readingList, int maxPages) {
    List<Book> result = new ArrayList<>();
    for (Book book : readingList){
        if (book.getNumPages() <= maxPages){
            result.add(book);
        }
    }
    return result;
}

Always try using abstractions (eg List) instead of real implementations (eg ArrayList) in declarations. 总是尝试在声明中使用抽象(例如List)而不是实际实现(例如ArrayList)。 It will allow you to change implementation in the future and be more flexible. 它将允许您在将来更改实施并更灵活。

Please refer to Liskov Principle - one of the SOLID principles. 请参阅Liskov原则 - SOLID原则之一。

You created a new list readingList2 , but you are not using it anywhere. 您创建了一个新列表readingList2 ,但您没有在任何地方使用它。 You are trying to change the list which you accepted as a formal parameter. 您正尝试将您接受的列表更改为形式参数。

Why not approach the problem a bit differently and return a new list with only the values you need? 为什么不稍微改变问题并返回一个只包含您需要的值的新列表?

Code Snippet: 代码片段:

public List<Book> filterBooks(List<Book> readingList, int maxPages) {
    List<Book> newReadingList = new ArrayList<>();
    for(final Book currentBook : readingList) {
        if(currentBook.getNumPages() < maxPages) {
           newReadingList.add(currentBook);
        }
    }
    return newReadingList;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM