如何只显示数组中的可用元素?

How to only show the available elements in an array?

如果我不“删除”数组中间的元素之一,我可以放置和“删除”我的数组中的元素并打印它们,因为我的代码只会显示直到0 出现,如果 0 是数组中的一个元素,则打印停止。 我试过这样做:

public static void showUsers() {
    for (int i = 0; i <= 100; i++) {
        if (users[i] == 0 && i == 0) {
            System.out.println("There's no users");
            //goes back to the main menu

            return;
        } else if (users[i] == 0) {
            //goes back to the main menu

            return;
        }
        System.out.println("List of Users: " + users[i]);
    }
    //goes back to the menu

    return;
}

我也尝试过使用 do-while 循环:

public static void showUsers() {
    int i = 0;

    if (users[i] == 0 && i == 0) {
        System.out.println("There's no users");
        //goes back to the main menu

        return;
    }

    do {
        if (users[i] == 0) {
            i++;
            return;
        }
        System.out.println("List of Users:" + users[i]);
        i++;
    } while (users[i] == 0 || i <= 100);

    //goes back to the main menu

    return;
}

因此,如果我创建 3 个用户,(1,2,3,0,0,0,....) 它将打印数字 1,2 和 3,但如果我“删除”数字 2,所以数组变为 (1,0,3,0,0,0,....) 它只会打印数字 1。我尝试过的两种情况都会发生这种情况。

我想要的是,“去掉”数字2之后,打印数字1和3。

我应该改变我的打印方式还是我“消除”的方式以及如何改变?

首先,为什么您的代码会这样运行?循环内的代码在循环的每次迭代中都是 运行。所以,如果你有一个 if 语句,并且 if 语句的 body 包含一个 return,那么只要该 if 语句在任何给定条件下为真,方法 returns迭代。

现在,修复您的代码。要跳过给定的迭代,请使用 continue 语句。这使得 for 循环继续进行下一次迭代,但是 not return 从该方法开始。对于“没有用户”检查,您可以使用布尔变量。您将其初始化为 true,每当您打印出一个用户时,您将其设置为 false。这样,在 for 循环之后,如果变量仍然为真,您就知道您没有用户。这是我对您的代码应用的两个修订:

public static void showUsers(){
    // declaring the boolean variable:
    boolean noUsers = true;

    System.out.println("List of Users:");

    // for loop loops over all the values of the array, not 100 times
    for (int i = 0; i < users.length; i++) {
        if (users[i] == 0) {
            // go to the next iteration
            continue;
        }

        // if we got this far, this element is not 0
        noUsers = false;
        System.out.println(users[i]);
    }

    //if noUsers is still true, we know there were no users other than 0's
    if (noUsers) {
        System.out.println("There's no users");
    }
}

我们在这里可以做的一项改进是使用增强的 for 循环。这允许您摆脱那个局部变量 i (它仍在内部使用,但我们不担心这里的性能)并且只处理数组元素。这是我的更新版本:

public static void showUsers(){
    boolean noUsers = true;

    System.out.println("List of Users:");

    // enhanced for loop is more concise and it covers up the i variable:
    for (int user : users) {
        if (user == 0) {
            continue;
        }

        noUsers = false;
        System.out.println(user);
    }

    if (noUsers) {
        System.out.println("There's no users");
    }
}

另一个改进是如果您希望“用户列表:”标题仅在有用户时出现。查看您的代码,这似乎是您想要的。为此,您可以只缓冲输出并稍后打印出来,而不是立即打印出来。如果您使用 StringBuilder 来缓冲输出,则可以在 for 循环之后检查 StringBuilder 是否为空,从而消除对布尔变量的需要。下面是我将如何实现它:

public static void showUsers(){
    // StringBuilder lets you build up a string without printing out
    // it is basically the same as a string, but it only performs the concatenation when
    // you tell it to
    StringBuilder output = new StringBuilder();

    for (int user : users) {
        if (user == 0) {
            continue;
        }

        // add the user to the StringBuilder instead of printing it out:
        output.append(user).append(System.lineSeparator());
    }

    if (output.length() == 0) {
        // if there are no users, the heading is not printed out
        System.out.println("There's no users");
    } else {
        System.out.println("List of Users:");

        // this causes an implicit call to the StringBuilder's toString() method,
        // which performs the concatenation and gives you a string you can print out
        System.out.println(output);
    }
}

为此,您可以使用方法 IntStream.filter

int[] users = {1, 0, 2, 3, 0, 0};

Arrays.stream(users)
        // filter out zero users
        .filter(user -> user != 0)
        // print users in one line
        .forEach(user -> System.out.println(user + ", "));

输出:

1, 2, 3,