如何解决这个错误:"类型不匹配:无法将List<String>转换为Iterator<String>"?

3

我是java8和spark的新手,我正在尝试在java中执行简单的flatmap转换程序,但我在倒数第二行的flatmap转换中遇到了一些错误 Arrays.asList(e.split(" ")));,错误是

类型不匹配:无法将 List<String> 转换为 Iterator<String>

这个问题应该怎么解决呢? 提前感谢。

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

 import org.apache.spark.SparkConf;
 import org.apache.spark.api.java.JavaRDD;
 import org.apache.spark.api.java.JavaSparkContext;
 import org.apache.commons.lang.StringUtils;

 public class FlatMapExample {
           public static void main(String[] args) throws Exception {
    SparkConf sparkConf = new 
          SparkConf().setMaster("local").setAppName("filter 
          transformation");
    JavaSparkContext sc = new JavaSparkContext(sparkConf);



    // Parallelized with 2 partitions
    JavaRDD<String> rddX = sc.parallelize(
            Arrays.asList("spark rdd example", "sample example"),
            2);

    // map operation will return List of Array in following case
    JavaRDD<String[]> rddY = rddX.map(e -> e.split(" "));

    List<String[]> listUsingMap = rddY.collect();
    for(int i = 0; i < listUsingMap.size(); i++)
    {
        System.out.println("list.."+StringUtils.join(listUsingMap.get(i)));
    }
    //System.out.println("listUsingMap..."+listUsingMap.collect());

    // flatMap operation will return list of String in following case
    JavaRDD<String> rddY2 = rddX.flatMap(e -> Arrays.asList(e.split(" ")));
    List<String> listUsingFlatMap = rddY2.collect();
}

}


8
List.iterator()是Java中List接口的一个方法,它返回一个迭代器对象,可以用于遍历List中的元素。 - Elliott Frisch
2个回答

4

您应该明确指定您正在使用至少版本 2.0,其中 FlatMapFunction::call 实际上返回一个 Iterator 而不是 Iterable(例如在 1.6 版本中就是这种情况)。因此,您的 rddX.flatMap 应该返回一个 Iterator<String>,而 Arrays.asList(e.split(" ")) 返回一个 List<String>

但是您可以使用 List::iterator,如下:

 rddX.flatMap(e -> Arrays.asList(e.split(" ")).iterator())

1
I would like to explain little more, hope would be helpful to you and others who face the same problem.
In Spark 1.6 and Spark 2.0, rdd.flatMap((e -> Arrays.asList(e.split(" "))) is correct.
Also, rddX.flatMap(e -> Arrays.asList(e.split(" ")).iterator()) is correct.
The flatMap method signature is as follows, which takes FlatMapFunction as a parameter: public <U> JavaRDD<U> flatMap(FlatMapFunction<T, U> f) For Spark 1.6, the FlatMapFunction's call method returns Iterable.
@FunctionalInterface
public interface FlatMapFunction<T, R> extends Serializable {
   Iterable<R> call(T t) throws Exception
}

Spark 2.0 FlatMapFunction

调用方法返回迭代器

@FunctionalInterface
public interface FlatMapFunction<T, R> extends Serializable {
    Iterator<R> call(T var1) throws Exception;
}

因此,在Spark 1.6中,flatMap方法需要一个返回Iterable的lambda表达式(Java 8),而在Spark 2.0中需要返回类型为Iterator。现在,rddX.flatMap(e -> Arrays.asList(e.split(" ")))中的Arrays.asList(e.split(" "))返回一个java.util.List,而List是一个Iterable。List实现了Collection。
public interface List<E> extends Collection<E>

Collection实现了Iterable接口。

public interface Collection<E> extends Iterable<E>

所以在Spark 1.6中,Arrays.asList()可以正常工作,但在Spark 2.0中需要进一步调用此列表上的iterator()方法来获取迭代器。
Arrays.asList(e.split(" ")).iterator()

讲解得很清楚。 - sparkingmyself

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接