Home > Software engineering >  How to cross iterate two arrayList in Java?
How to cross iterate two arrayList in Java?

Time:10-27

I have two arrayLists for now, and I want to do cross-iterations of them (basically, first iterate the 1st element in the first arrayList, and then iterate the 1st element in the second arrayList, next iterate the 2nd element in the first arrayList etc.). I am wondering how should I achieve this functionality?

Here is a simple test code:

public static void main(String[] args) {

        ArrayList first = new ArrayList();

        first.add("a");
        first.add("c");
        first.add("e");

        ArrayList second = new ArrayList();

        second.add("b");
        second.add("d");

        System.out.println(first);
        System.out.println(second);

    }

So basically, I would like to first extract the String a and do some coding, then String b, then String c, then d and e (note that the number of elements in the second arrayList is always one smaller then the first one).

Any hints will be much appreciated :)

CodePudding user response:

Based on the explanation given in one of the comments, the List first should be renamed to actions and the List second should be moves. Further there is always one final action after the last move, and the processing always starts with an action.

Try this (but replace the '?' by something useful first):

public final void process( final List<?> a, final List<?> m )
{
  if( a.size() != m.size()   1 ) throw IllegalArgumentException( … );
  final Queue<?> actions = new LinkedList<>( a );
  final Queue<?> moves = new LinkedList<>( m );
  
  while( !moves.isEmpty() )
  { 
    final var action = actions.remove();
    final var move = moves.remove();

    doAction( action );
    doMove( move );
  }
  final var action = actions.remove();
  doAction( action );
  
  assert actions.isEmpty();
  assert moves.isEmpty(); 
}

Call this as

process( first, second );

Of course you can avoid the the local variables by using the return value from Queue.remove() as the argument to the do…() methods.

CodePudding user response:

You can iterate both lists from 0 until to second.size(), as you said second is always smaller.

And with a second for-loop iterate the rest elements from second.size() until to first.size()

ArrayList<String> first = new ArrayList<>();
first.add("a"); first.add("c");
first.add("e"); first.add("f");
first.add("g");

ArrayList<String> second = new ArrayList<>();
second.add("b");second.add("d");

for(int i = 0; i < second.size(); i  ){
    System.out.println(first.get(i).toUpperCase());
    System.out.println(second.get(i).toLowerCase());
}

//iterate the rest elements remained in first
for(int i = second.size(); i < first.size(); i  ){
    System.out.println(first.get(i).toUpperCase());
}

CodePudding user response:

You could use a for loop with two counters and iterate from 0 to first.length

counterForFirst ( i in the foor loop ) = 0; counterForSecond = 0;

inside the loop, you would increment counterForSecond as well.

To avoid ArrayIndexOutOfBoundsException you could check if(counterForSecond < second.length ) in every itiration.

for (int counterForFirst = 0; counterForFirst < first.size(); counterForFirst  ) {

         // action on first[counterForFirst]

         if(counterForFirst < seconds.length)
         {      
            // action on seconds 

              counterForSecond    ;
         }

      }     

CodePudding user response:

Since you know that first list is larger than second you can just iterate based on first list size and then add the elements to a third list. You need to check that the iteration value is still applicable to the second list. Having said that the following should work:

ArrayList first = new ArrayList();

first.add("a");
first.add("c");
first.add("e");

ArrayList second = new ArrayList();

second.add("b");
second.add("d");

System.out.println(first);
System.out.println(second);

ArrayList<Object> result = new ArrayList<>();
for (int i = 0; i < first.size(); i  ) {
    result.add(first.get(i));
    if (i < second.size()) {
        result.add(second.get(i));
    }
}
System.out.println(result);

CodePudding user response:

I would stream over the indices in the range between 0 and first.size second size. If like you said

the number of elements in the second arrayList is always one smaller then the first one

then first.size second.size = first.size * 2 - 1 and even indices can be mapped to elements of first list and odd indices to elements of second list.

ArrayList<String> first = new ArrayList<>();
first.add("a");
first.add("c");
first.add("e");
first.add("g");
ArrayList<String> second = new ArrayList<>();
second.add("b");
second.add("d");
second.add("f");

IntStream.range(0, first.size() * 2 - 1).forEach(i ->{
    String current;
    if(i % 2 == 0){
        current = first.get(i/2);
        System.out.println(current); // print or do something else with current
    }
    else {
        current = second.get(i/2);
        System.out.println(current); // print or do something else with current
    }
});
  • Related