0

I have three lists: listA, listB, listC.

listA        listB
1,a,tf       b,true
2,b,tf       a,false
3,c,tf       c,true

and I would like to have listC to be listA + listB in order of listA (replacing listA's tf with listB's true/false).

listC
1,a,false
2,b,true
3,c,true

Here's my code

Iterator a= listA.iterator();
Iterator b= listB.iterator();
    while(a.hasNext()){
        while(b.hasNext()){
            if(String.valueOf(a.next()).split(",")[1].equals(String.valueOf(b.next()).split(",")[0])){
                    listC.add(String.valueOf(a.next()).replaceAll("tf", String.valueOf(b.next()).split(",")[1]));
            }
        }
    }

With individual iterator-while for listA and listB being split and indexed, it works fine, but when I run the code above, the program just freezes. Any thoughts?

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
Miko
  • 156
  • 2
  • 14
  • I'm not sure about that freeze but using iterators that way will most likely not have the result you expect. You should read on what `hasNext()` and `next()` are meant to do and thus you'd probably realize that calling `next()` multiple times after a call to `hasNext()` (as you do for `a` and `b` inside your if-statement and additionally for `a` in the b-loop) is _not_ a good idea. – Thomas Jul 18 '17 at 15:14
  • 1
    Having Map instead of ListB would make your life easier. Also making your own class for `1,a,tf` could help you easier create your conditions rather than splitting string. If you apply those changes your code could look like `for (YourClass yc : listA){yc.setTrueFalse(mapB.get(yc.getName()));}`. This would actually update elements of listA, but you can build your solution which will create separate listC easily. – Pshemo Jul 18 '17 at 15:21

1 Answers1

1

You're really not far off. Iterators can be confusing and so I tend to avoid them.

I can't really see where the infinite loop is in your code - I expected a NullPointerException because you're calling a.next() and b.next() multiple times.

If you change your code to remove the iterators, it works fine:

List<String> listA = Arrays.asList("1,a,tf", "2,b,tf", "3,c,tf");
List<String> listB = Arrays.asList("b,true", "a,false", "c,true");
List<String> listC = new ArrayList<>();

for(String a : listA)
{
    for (String b : listB)
    {
        if (String.valueOf(a).split(",")[1].equals( String.valueOf(b).split(",")[0] ) )
        {
            listC.add(String.valueOf(a).replaceAll("tf", String.valueOf(b).split(",")[1]));
        }
    }
}

System.out.println(listC.toString());
Michael
  • 41,989
  • 11
  • 82
  • 128
  • Whoops, I was actually looping the collections like that when I was in college, but I've never thought of this now, really. I was always thinking of iterator everytime it involves collection. But do you know what went wrong with iterating the lists with multiple whiles? BTW +1 for you bud, this has killed me for several hours. whew – Miko Jul 19 '17 at 16:12
  • It's *something* to do with calling `a.hasNext()` once then `a.next()` twice. It'll shoot you over the end of the array. My intuition says it shouldn't result in an infinite loop, but rather a crash, but obviously I'm wrong. FYI, this style of for-each [actually does use iterators "under the hood"](https://stackoverflow.com/questions/85190/how-does-the-java-for-each-loop-work) so its no different from you wrote (except your double `a.next()`), it just looks nicer. – Michael Jul 19 '17 at 16:28