java.lang.ClassCastException:scala.Tuple2无法强制转换为java.lang.Iterable

时间:2015-06-04 14:09:19

标签: java apache-spark

在Spark中使用Java,我想解析一个名为artist_data.txt的文本文档; 我首先创建了JavaRDD;

JavaRDD rawArtistData = sc.textFile(" src / main / resources / artist_data.txt"); 现在解析具有Tab sperator但也有坏行的文档,其中行数似乎已损坏。它们不包含标签, 或者他们无意中包含换行符。所以我需要使用flatMap方法;

现在通过运行下面的代码,我收到了一个错误; java.lang.ClassCastException:scala.Tuple2无法强制转换为java.lang.Iterable



JavaRDD<Tuple2<Integer, String>> artistByID0 = rawArtistData
					.flatMap(new FlatMapFunction<String, Tuple2<Integer, String>>() {
						private static final long serialVersionUID = 1L;
						@SuppressWarnings("unchecked")
						public Iterable<Tuple2<Integer, String>> call(String s) {
							 String[] sarray = s.split("\t");
							return (Iterable<Tuple2<Integer, String>>) new Tuple2<Integer, String> 
							(Integer.parseInt(sarray[0]), sarray[1].trim());
						}
					});
		 
		  
		  JavaPairRDD<Integer, String> artistByID = JavaPairRDD.fromJavaRDD(artistByID0);
		  
		  System.out.println(artistByID.count());
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为flatMap需要一个列表列表,它会将内部列表截断为一个列表。当您一次性拆分和解析时,您实际上只需要map函数,它将直接返回Tuple

flatMap的一个更典型的用例是直接从分割返回数组,这将导致所有数组被截断为一个列表,这样你就可以拥有所有单词而不是一堆单独的列表的话。

根据您的评论,听起来您显示的代码示例不会显示您的真实用例。如果你有可能因为数据不好而没有返回任何内容,那么你会想要如下内容:

JavaRDD<Tuple2<Integer, String>> artistByID0 = rawArtistData
                .flatMap(new FlatMapFunction<String, Tuple2<Integer, String>>() {
                    private static final long serialVersionUID = 1L;
                    @SuppressWarnings("unchecked")
                    public Iterable<Tuple2<Integer, String>> call(String s) {
                         String[] sarray = s.split("\t");
                         List<Tuple2<Integer, String>> returnList = new ArrayList<Tuple2<Integer, String>>();
                         if(sarray.length >= 2) 
                           returnList.add(new Tuple2<Integer, String> (Integer.parseInt(sarray[0]), sarray[1].trim()));
                         return returnList;
                        );
                    }
                });

请注意,如果拆分成功拆分为2个或更多项,现在只返回包含项目的列表。

答案 1 :(得分:-1)

简短的回答是你告诉FlatMapFunction你正在返回一个可迭代的Tuple2。显然FlatMapFunction期望返回您在类中定义的迭代。最简单的答案是创建一个LinkedList&gt;,只添加元组并返回它。

这是一个可能会对API进行更新的更改。

public Iterable<Tuple2<Integer, String>> call(String s) {
    String[] sarray = s.split("\t");
    LinkedList<Tuple2<Integer, String>> r = new LinkedList<>();
    Tuple2<Integer, String> t = new Tuple2<Integer, String> (Integer.parseInt(sarray[0]), sarray[1].trim());
    r.add(t)
    return r;
}

长答案真的是一个问题:为什么不使用Scala?它是最基本的Java。你可以从那里开始工作。