MerielWinter134
MerielWinter134

Reputation: 21

Java arrayList for loop index out of bounds when combining two arrays of different length

I'm just learning java and working on a homework problem. Our assignment was two read two-word lists into arrays and then combine them into one ArrayList alternating the words in the list. e.g. L1[0], L2[0], L1[1], L2[1], etc.

I've got my code almost running EXCEPT if the word lists are not exactly the same length, I either leave off the last words in the long list or get an out-of-bounds index for the shorter list. I know there must be an obvious solution I haven't thought of. Thanks for your help!

Here is the code I've written:

public class ArrayMixer {
    public static void main (String[] args){
        Scanner scnr= new Scanner(System.in); // set up scanner

        // Initialize variables to capture user inputs
        String firstLine;
        String secondLine;

        //collect user input for the first list
        System.out.println("Please enter the first word list:"); // prompt user for first list
        firstLine= scnr.nextLine();
        String[] firstArray= firstLine.split(" "); // creates array to store first line split by spaces

        //System.out.println(firstLine);//FIXME COMMENT OUT AFTER TESTING
        //System.out.println(Arrays.toString(firstArray));//FIXME COMMENT OUT AFTER TESTING

        //collect user input for the second list
        System.out.println("Please enter the second word list:");// prompt user for second list
        secondLine= scnr.nextLine();//
        String[] secArray= secondLine.split(" ");//create array to store second list split by spaces

        //System.out.println(secondLine);//FIXME COMMENT OUT
        //System.out.println(Arrays.toString(secArray)); //FIXME COMMENT OUT


        //Create an array list called mixList to store combination of list 1 and 2
        ArrayList <String> mixList = new ArrayList<String>();

        // need to find out size of two lists put together
        int mixSize= (firstArray.length + secArray.length);
        System.out.println(mixSize);

        
//HERE IS MY PROBLEM I've replace secArray.length w/ mxSize, and firstArray.length NO DICE
for (int i=0; i< secArray.length; ++i) {//FIXME NEED TO FIGURE OUT HOW TO GET THE LOOP
            // NOT GO OUT OF BOUNDS
            mixList.add(firstArray[i]);
            mixList.add(secArray[i]);
        }

        //print new list to output
        for (int i=0; i< mixList.size(); ++i) {
            String tempWord=mixList.get(i);
            System.out.println(tempWord);
        }

    }
}

I've tried using the length of the two lists combined and the length of the longer list-> index out of bounds, the shorter list- last words of the longer list left off because the loop never gets to their index.

Is there some sort of special arrayList for loop I can use?

Upvotes: 1

Views: 378

Answers (4)

MerielWinter134
MerielWinter134

Reputation: 21

Thanks for your help everyone! Here is the solution I ended up on.

    ArrayList <String> mixList = new ArrayList<String>();

    // This scenario accounts for a shorter first list of words
    if (firstArray.length < secArray.length) {

        // This alternates the words until first list is exhausted
        for (int i = 0; i < firstArray.length; ++i) {
            mixList.add(firstArray[i]);
            mixList.add(secArray[i]);
        }
        //this adds the remaining words from the longer list on to the end
        for (int i = firstArray.length; i < secArray.length; ++i) {
            mixList.add(secArray[i]);
        }
    }
    //This accounts for when the second list is shorter or if they are the same length
    else {
        // This alternates the words until second list is exhausted
        for (int i = 0; i < secArray.length; ++i) {
            mixList.add(firstArray[i]);
            mixList.add(secArray[i]);
        }
        //this adds the remaining words from the longer list on to the end
        //If lists are the same length, the list will not execute
        for ( int i = secArray.length; i < firstArray.length; ++i) {
            mixList.add(firstArray[i]);
        }
    }

    //print new list to output
    for (int i=0; i< mixList.size(); ++i) {
        String tempWord=mixList.get(i);
        System.out.println(tempWord);
    }

Upvotes: 1

Andreas Siegel
Andreas Siegel

Reputation: 1098

I would do it exactly like Dreamspace President's answer. I think it should be the accepted one.

However, I would at least like to propose an alternative approach.

The reasoning behind this is that the new list was expected to contain alternating entries from the original arrays. If one array is much shorter than the other one, the result would only start with alternating values but end with just the "rest" of the larger array.

If this was unwanted behavior, you could also stop processing the arrays:

You already saw the exception, and you know that it will definitely be thrown when you are dealing with arrays that have different lengths. So you could also catch the exception and jump out of the loop:

final int largerArray = Math.max(firstArray.length, secondArray.length);
for (int i = 0; i < largerArray; i++) {
  try {
    mixList.add(firstArray[i]);
    mixList.add(secondArray[i]);
  } catch (IndexOutOfBoundsException e) {
    // one array is longer than the other, we cannot alternate any longer
    // -> jumping out of the loop
    break;
  }
}

Upvotes: 1

Dreamspace President
Dreamspace President

Reputation: 1118

final String[] firstArray = firstLine.split(" ");
final String[] secondArray = secondLine.split(" ");
final List<String> mixList = new ArrayList<>();

final int largerArray = Math.max(firstArray.length, secondArray.length);
for (int i = 0; i < largerArray; i++) {
    
    if (i < firstArray.length) {
        mixList.add(firstArray[i]);
    }
    if (i < secondArray.length) {
        mixList.add(secondArray[i]);
    }
}

Upvotes: 2

WJS
WJS

Reputation: 40062

Here is one way to combine them. You will need to adapt this to your specific requirements.

 List<Integer> evens = List.of(2, 4, 6, 8, 10, 12);
 List<Integer> odds = List.of(1, 3, 5);
 List<Integer> combined = new ArrayList<>();
 for (int i = 0, k = 0; i + k < evens.size() + odds.size(); ) {
     if (i < odds.size()) {
         combined.add(odds.get(i++));
     }
     if (k < evens.size()) {
         combined.add(evens.get(k++));
     }
 }
 System.out.println(combined);

And here is another.

 for (int i = 0; i < Math.max(odds.size(), evens.size()); i++) {
    if (i < odds.size()) {
        combined.add(odds.get(i));
    }
    if (i < evens.size()) {
        combined.add(evens.get(i));
    }
 }
 System.out.println(combined);

both print

[1, 2, 3, 4, 5, 6, 8, 10, 12]

Upvotes: 1

Related Questions