0

What I am trying to accomplish is simple: Return the list containing a Tuple2 as a Java Iterator.

The code snippet is:

....public java.util.Iterator<Tuple2<Path, Text>> call(InputSplit inputSplit, java.util.Iterator<Tuple2<LongWritable, Text>> iter) throws Exception { 


    .....  java.util.List<Tuple2<Path, Text>>  elements = new java.util.ArrayList<Tuple2<Path, Text>>();
        while(iter.hasNext()){
            Tuple2<LongWritable,Text> tupled = iter.next();
            Tuple2<Path, Text> toAdd = new Tuple2<Path, Text>(file.getPath(),tupled._2);
            elements.add(toAdd);
        }
        java.util.Iterator<Tuple2<Path, Text>> it = elements.iterator();
        return it; .....}

Note: the variable iter is also a Java Iterator.

The error I get is: java.lang.ClassCastException: java.util.ArrayList$Itr cannot be cast to scala.collection.Iterator

  1. What am I doing wrong? (I am aware that I am using Tuple2, which is meant for Scala).
  2. How do I return a Java Iterator with a Tuple2 or a Tuple2 equivalent ?

Thank you

DNA
  • 42,007
  • 12
  • 107
  • 146
3xCh1_23
  • 1,491
  • 1
  • 20
  • 39

2 Answers2

3

Looks like you're doing an illegal cast from Java iterator to Scala iterator.

Try using scala.collection.JavaConversions. When you import this implicit class - these conversions will be done automatically.

In short -

import scala.collection.JavaConversions._

Another option is to do it explicitly, assuming javaIterator is your java iterator -

import scala.collection.JavaConverters._
javaIterator.asScala
Maxim
  • 7,268
  • 1
  • 32
  • 44
  • Thank you, I would like to ask where exactly to use it, since the error appears in the line::: java.util.Iterator> it = elements.iterator(); ::: I have tried casting it at the end (at the return) and it did not work. EDIT: OK I have some idea... will let you know. – 3xCh1_23 Apr 14 '15 at 15:28
  • As I said you shouldn't cast. You should: `import scala.collection.JavaConversions._` and it will do the conversion for you implicitly – Maxim Apr 14 '15 at 15:30
  • still the same problem, but thank you for answering. I will try to cast the collection first, then get the Scala iterator, then cast it back to Java, just for fun. – 3xCh1_23 Apr 14 '15 at 15:34
  • Edited my comment. Please retry. Don't try to cast it - it won't work. – Maxim Apr 14 '15 at 15:35
  • If you prefer to do this explicitly you can `import scala.collection.JavaConverters._` and then javaIterator.asScala – Maxim Apr 14 '15 at 15:37
  • Perhaps your solution(s) will work for someone else. Thank you. – 3xCh1_23 Apr 14 '15 at 15:53
1

Maxim answer is correct, here is exact java code which will do conversion:

import scala.collection.JavaConversions;
List<String> javaBatch = new ArrayList<String>();
scala.collection.Iterable<String> scalaBatch =  JavaConversions.asScalaIterable(javaBatch);

Similarly, method JavaConversions.asScalaIterator() can be used for iterators. Vice-versa is also possible.

Community
  • 1
  • 1
Mayank Raghav
  • 640
  • 1
  • 7
  • 17