Bruno Silva
Bruno Silva

Reputation: 25

How to only show the available elements in an array?

I can put and "remove" the elements in my array as well print them, if I don't "remove" one of the elements in the middle of the array, because my code only makes it to show until 0 shows up, if a 0 is an element in the array the print stops. I've tried doing this:

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

I've tried using a do-while loop as well:

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

So if I create 3 users, (1,2,3,0,0,0,....) it will print the numbers 1,2 and 3 but if I "remove" the number 2, so the array becomes (1,0,3,0,0,0,....) it will only print the number 1. This happens to both of the cases I've tried.

What I wanted, after "removing" the number 2, it's to print the number 1 and 3.

Should I change the way I print or the way I "eliminate" and how?

Upvotes: 0

Views: 393

Answers (2)

user14940971
user14940971

Reputation:

You can use method IntStream.filter for this purpose:

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 + ", "));

Output:

1, 2, 3, 

Upvotes: 0

Charlie Armstrong
Charlie Armstrong

Reputation: 2342

First, why does your code behave the way it does? The code inside a loop is run on every iteration of the loop. So, if you have an if statement in there, and the body of the if statement contains a return, then the method returns as soon as that if statement is true on any given iteration.

Now, to fix your code. To skip a given iteration, use the continue statement. This makes the for loop go on to the next iteration, but does not return from the method. For your "there's no users" check, You can use a boolean variable. You initialize it to true, and whenever you print out a user, you set it to false. This way, after the for loop, if the variable is still true, you know you had no users. Here are my two revisions applied to your code:

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

One improvement we can make here is using the enhanced for loop. This allows you to get rid of that local variable i (it is still used internally, but we're not worried about performance here) and only handle the array elements. Here's my updated version:

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

Another improvement is if you want the "List of Users:" heading to only appear if there are users. Looking at your code, this seems to be what you want. To achieve this, you can just buffer the output and print it out later, rather than printing it out right away. If you use a StringBuilder to buffer the output, you can check if the StringBuilder is empty after the for loop, thus removing the need for a boolean variable. Here's how I would implement this:

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

Upvotes: 2

Related Questions