简体   繁体   中英

Get next item in list that is not in another list in Java

I'm trying to make a function to get the next item in a list that is not in another list, while also looping to the beginning of the list when it reaches the end.

Basically what I want to happen is:

String[] list = new String[]{"apple", "banana", "cherry", "donut", "egg", "fish", "grape"};
List<String> list2 = new ArrayList<String>( Arrays.asList("apple", "cherry", "donut", "fish"));
int index = 4;
System.out.println(nextItem());
System.out.println(nextItem());
System.out.println(nextItem());
System.out.println(nextItem());
System.out.println(nextItem());
//Returns:
//egg
//grape
//banana
//egg
//grape

I have tried doing this:

public String nextItem() {
    index++;
    if(index == list.size()) index = 0;
    while(list2.contains(list[index])) {
        index++;
        if(index == list.size()) index = 0;
    }
    return list[index];
}

but that does not work, the index just stays the same.

Is there a better way to do this/something similar to this that I don't know of?

A few changes and it works like a charm:

public class Example {
    String[] list = new String[]{"apple", "banana", "cherry", "donut", "egg", "fish", "grape"};
    List<String> list2 = new ArrayList<>(Arrays.asList("apple", "cherry", "donut", "fish"));
    public int index = 4;

    public static void main(String[] args) {
        new Example().start();
    }

    public void start() {
        for (int i = 0; i < 100000; i++) {
            System.out.println(nextItem());
        }
    }

    public String nextItem() {
        index++;
        if (index == list.length) index = 0;
        while (list2.contains(list[index])) {
            index++;
            if (index == list.length) index = 0;
        }
        return list[index];
    }
}

The main point being that index must be global.

Depends where list and list2 are declared. I would suggest supplying the String Array (list) and the List Interface (list2) as arguments to the nextItem() method as well as a Starting Index value as a third argument, for example:

public static int nextItem(String[] stringArray, List<String> listInterface, int startIndex) {
    int index = -1;
    for (int i = startIndex; i < stringArray.length; i++) {
        if (!listInterface.contains(stringArray[i])) {
            return i;
        } 
    }
    return -1;
}

The above example nextItem() method returns an Integer value which would be the index value at which an item within the String Array (list) is not also contained within the List Interface collection (list2). Your natural first call to this method would supply a 0 as the argument for the startIndex parameter. To get the next item which is not shared in both list and list2 , you would supply the the returned index value from the previous nextItem() call, add 1 , and provide it as the startIndex value to the next nextItem() method call. Here's an example:

String[] list = {"apple", "banana", "cherry", "donut", "egg", "fish", "grape"};
List<String> list2 = new ArrayList<>( Arrays.asList("apple", "cherry", "donut", "fish"));

int idx = 0;
while (idx != -1) {
    idx = nextItem(list, list2, idx);
    if (idx != -1) {
        System.out.println(list[idx]);
        idx++;
    } 
}

The Console Window would display:

banana
egg
grape  

The following example code doesn't use a loop and is supplied here to perhaps be a better visual aid to what the code is doing:

String[] list = {"apple", "banana", "cherry", "donut", "egg", "fish", "grape"};
List<String> list2 = new ArrayList<>( Arrays.asList("apple", "cherry", "donut", "fish"));

String noMore = "** There are no more non-shared items in the lists! **";

// Get first non-shared item
int idx = nextItem(list, list2, 0);
if (idx > -1) {
    System.out.println(list[idx]);
}
else {
    System.out.println("Both lists contain all the same items");
    // return from method or event
}

// Get second non-shared item
idx = nextItem(list, list2, idx + 1);
if (idx > -1) {
    System.out.println(list[idx]);
}
else {
    System.out.println(noMore);
    // return from method or event
}

// Get third non-shared item
idx = nextItem(list, list2, idx + 1);
if (idx > -1) {
    System.out.println(list[idx]);
}
else {
    System.out.println(noMore);
    // return from method or event
}

// Get fourth non-shared item (if any)
idx = nextItem(list, list2, idx + 1);
if (idx > -1) {
    System.out.println(list[idx]);
}
else {
    System.out.println(noMore);
    // return from method or event
}

The console Window would display:

banana
egg
grape
** There are no more non-shared items in the lists! **

The key is to keep increasing index till an element from list is found in list2 . I have done it using the while loop in the program given below:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    static String[] list = new String[] { "apple", "banana", "cherry", "donut", "egg", "fish", "grape" };
    static List<String> list2 = new ArrayList<String>(Arrays.asList("apple", "cherry", "donut", "fish"));
    static int index = 4;

    public static void main(String[] args) {
        System.out.println(nextItem());
        System.out.println(nextItem());
        System.out.println(nextItem());
        System.out.println(nextItem());
        System.out.println(nextItem());
    }

    static String nextItem() {
        if (index == list.length) {
            index = 0;
        }
        while (list2.contains(list[index])) {
            index++;
        }
        return list[index == list.length ? 0 : index++];
    }
}

Output:

egg
grape
banana
egg
grape

Feel free to comment in case of any issue/doubt.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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