为什么 Java for-each 循环对数组中的所有对象执行方法?

Why does Java for-each loop execute methods on all objects in array?

提问人:AzureBoredom 提问时间:6/1/2023 最后编辑:Mark RotteveelAzureBoredom 更新时间:6/1/2023 访问量:68

问:

我是编码的初学者,并试图为一个简单的项目实现一个 Java for-each 循环。有问题的项目具有类 LibraryMember 和 Book,类 Library 包含其他两个类作为 ArrayList 类型的属性。我希望能够循环浏览这两个数组,以辨别哪些 LibraryMember 和哪些书籍可用,然后对它们执行适当的操作,例如标记 Book checked out (unavailable) 和 increment of Books bidout by LibraryMember。

public void borrowBook(String name, String title) {
    LibraryMember lm = findMember(name);
    Book b = findBook(title);
    if (lm != null && b != null) {
        for (LibraryMember libMem : libMems) {
            for (Book book : books) {
                if(book.isAvailability() && libMem.getNumBorrowed()<4) {
                    book.setAvailability(false);
                    libMem.addBorrow(libMem);
                    System.out.println(title + " has been borrowed by " + name);
                    break;
                } else if(!book.isAvailability()) System.out.println(title + " is unavailable.");
                else System.out.println(name + " has too many books.");
            }
        }
    } else if(lm==null) System.out.println(name + " could not be found.");
    else System.out.println(title + " could not be found.");
}

当代码运行时,这些方法将作用于数组中的每个对象。我知道这是因为当满足初始条件时,for-each 循环继续循环遍历数组的每个成员并执行方法。if (lm != null && b != null)

有人可以告诉我这是为什么吗?为什么代码不只作用于满足循环前概述的条件的对象?即 和。我该如何解决这个问题?if (lm != null && b != null)if(book.isAvailability() && libMem.getNumBorrowed()<4)

Java 数组 foreach

评论

0赞 experiment unit 1998X 6/1/2023
你能进一步澄清你的意思吗?有点难以理解你希望实现的目标
0赞 markspace 6/1/2023
换句话说,请向我们展示重现问题的代码。您希望看到什么结果而不是当前结果。
1赞 Scary Wombat 6/1/2023
当我怀疑这是您要处理的书时,为什么要遍历所有书籍 - 不是吗?Book b = findBook(title);
1赞 tgdavies 6/1/2023
除了检查它们是否为 null 之外,您从不使用 or 。lmb
0赞 Louis Wasserman 6/1/2023
为什么仅从这段代码来看,和 的任何特定元素之间会存在任何特定关系?for 循环的哪一部分检查了什么?lmlibMemslibMem

答:

0赞 Bill Mair 6/1/2023 #1

你有两个循环,你只是突破了一个循环,循环还在继续。forbookslibMems

for (LibraryMember libMem : libMems) {
    for (Book book : books) {
        if( ... ) {
            ...
            break;
        }

解决此问题的最简单方法是标记主循环,并使用该标签退出处理。break

这里添加了一个名为 的标签,添加标签是用名称和冒号完成的,然后使用该名称作为 break 语句的一部分。checkBorrowLoop:

checkBorrowLoop:
for (LibraryMember libMem : libMems) {
    for (Book book : books) {
        if( ... ) {
            ...
            break checkBorrowLoop;
        }

对逻辑的一个小评论:您应该在进行任何其他处理之前进行测试,因为如果其中任何一个都为真,则进行任何检查都没有意义。libMem.getNumBorrowed()>=4!book.isAvailability()

0赞 Thomas Kläger 6/1/2023 #2

for-each 循环执行它应该执行的操作:它遍历集合的所有成员。

从您提供的代码中,我认为您根本不需要循环,因为您已经引用了 和 :LibraryMemberBook

public void borrowBook(String name, String title) {
    LibraryMember lm = findMember(name);
    Book b = findBook(title);
    if (lm != null && b != null) {
        if (b.isAvailability() && lm.getNumBorrowed()<4) {
            b.setAvailability(false);
            lm.addBorrow(lm); // this line looks suspicious!!
            System.out.println(title + " has been borrowed by " + name);
        } else if (!book.isAvailability()) {
            System.out.println(title + " is unavailable.");
        } else {
            System.out.println(name + " has too many books.");
        }
    } else if (lm==null) {
        System.out.println(name + " could not be found.");
    } else {
        System.out.println(title + " could not be found.");
    }
}

请注意,这一行(在您的原始来源中)看起来很可疑:为什么图书馆成员会自己借阅?lm.addBorrow(lm);libMem.addBorrow(libMem);

评论

0赞 AzureBoredom 6/2/2023
感谢您的解释,此代码有效。