使用Foreach收集数据

时间:2016-07-18 06:19:29

标签: apache-spark java-8 rdd

我试图预先处理RDD并将数据收集到String构建器中。但是,由于foreach在执行程序节点上运行并且字符串构建器正在驱动程序节点上运行,因此它不会发生。有什么方法可以实现我的目标?我不想使用收集操作,因为它很昂贵。

public class login extends AppCompatActivity {
   @Override  

   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_login);
     EditText edittext = (EditText) findViewById(R.id.editText);
     String et = edittext.getText().toString();
     if(et.equals("ab123")) {
       System.out.println("asdfg");
     }
   }   
 }

任何帮助高度赞赏。

3 个答案:

答案 0 :(得分:1)

您可以使用rdd.aggregate将rdd中的所有字符串组合成单个StringBuffer,如下所示:

val rdd = sc.parallelize( List( "h" , "a" , "b" ) )
val res = rdd.aggregate( new StringBuffer )( ( sb:StringBuffer , str : String ) => sb.append( str ) , ( sb1 : StringBuffer , sb2 : StringBuffer ) => sb1.append( sb2 ) )
println( res ) // "abh"

显然,你的rdd的字符串的整个内容将在字符串缓冲区中连接,这可能是巨大的,但这就是你想要的...... 这比收集更好,因为字符串数据不是“原始”发送给驱动程序(仅以连接形式)。

另请注意,不保证字符串的顺序......

答案 1 :(得分:1)

我认为可能有另一种方式:累积器。这是关于如何使用字符串累加器的重定向:
Not able to declare String type accumulator
归功于该回复的作者

答案 2 :(得分:1)

您可以使用foreachPartition。这只会收集执行者的数据,而不是驱动程序中的数据。

javaRDD.foreachPartition(partition -> {
  StringBuilder builder = new StringBuilder();
  while (partition.hasNext()) {
    builder.append(partition.next());
  }
  System.out.println(builder.toString() + " ****");
});