Java 如何在ApacheSpark中重置MapReduce函数上的迭代器

Java 如何在ApacheSpark中重置MapReduce函数上的迭代器,java,hadoop,mapreduce,apache-spark,yarn,Java,Hadoop,Mapreduce,Apache Spark,Yarn,我是Apache Spark的新手。我想知道如何在ApacheSpark中的MapReduce函数中重置指向迭代器的指针,以便编写 Iterator<Tuple2<String,Set<String>>> iter = arg0; 迭代器iter=arg0; 但它不起作用。下面是一个用java实现MapReduce函数的类 class CountCandidates implements Serializable, PairFlatMapF

我是Apache Spark的新手。我想知道如何在ApacheSpark中的MapReduce函数中重置指向迭代器的指针,以便编写

Iterator<Tuple2<String,Set<String>>> iter = arg0;    
迭代器iter=arg0;
但它不起作用。下面是一个用java实现MapReduce函数的类

class CountCandidates implements Serializable,
    PairFlatMapFunction<Iterator<Tuple2<String,Set<String>>>, Set<String>, Integer>,
    Function2<Integer, Integer, Integer>{

    private List<Set<String>> currentCandidatesSet;
    public CountCandidates(final List<Set<String>> currentCandidatesSet) {
        this.currentCandidatesSet = currentCandidatesSet;
    }

    @Override
    public Iterable<Tuple2<Set<String>, Integer>> call(
            Iterator<Tuple2<String, Set<String>>> arg0)
            throws Exception {
        List<Tuple2<Set<String>,Integer>> resultList = 
                new LinkedList<Tuple2<Set<String>,Integer>>();

        for(Set<String> currCandidates : currentCandidatesSet){
            Iterator<Tuple2<String,Set<String>>> iter = arg0;
            while(iter.hasNext()){
                Set<String> events = iter.next()._2;
                if(events.containsAll(currCandidates)){
                    Tuple2<Set<String>, Integer> t = 
                            new Tuple2<Set<String>, Integer>(currCandidates,1);
                    resultList.add(t);
                }
            }
        }

        return resultList;
    }

    @Override
    public Integer call(Integer arg0, Integer arg1) throws Exception {
        return arg0+arg1;
    }
}
类countable实现可序列化,
PairFlatMapFunction,
功能2{
私有列表集;
公共候选名单(最终候选名单集){
this.CurrentCandidateSet=CurrentCandidateSet;
}
@凌驾
公共电话(
迭代器arg0)
抛出异常{
列表结果列表=
新建LinkedList();
for(设置当前候选项:CurrentCandidateSet){
迭代器iter=arg0;
while(iter.hasNext()){
设置事件=iter.next();
if(事件包含所有(当前候选)){
tuple2t=
新的Tuple2(1);
结果列表添加(t);
}
}
}
返回结果列表;
}
@凌驾
公共整数调用(整数arg0、整数arg1)引发异常{
返回arg0+arg1;
}
}
如果无法在函数中重置迭代器,如何迭代参数arg0几次?我已经尝试了一些不同的方法,如下面的代码,但它也不起作用。下面的代码似乎“resultList”的数据比我预期的要多

        while(arg0.hasNext()){
            Set<String> events = arg0.next()._2;
            for(Set<String> currentCandidates : currentCandidatesSet){
                if(events.containsAll(currentCandidates)){
                    Tuple2<Set<String>, Integer> t = 
                            new Tuple2<Set<String>, Integer>(currentCandidates,1);
                    resultList.add(t);
                }
            }
        }
while(arg0.hasNext()){
设置事件=arg0.next();
for(设置当前候选项:CurrentCandidateSet){
if(events.containsAll(当前候选)){
tuple2t=
新的元组2(当前候选,1);
结果列表添加(t);
}
}
}
我怎样才能解决它


提前谢谢你的回答,我的英语很差。如果您不理解我的问题,请发表评论。

即使在普通Java或Scala中,
迭代器也无法“重置”。这就是
迭代器的本质。
Iterable
可以多次为您提供迭代器。您的代码需要重写才能接受可写的,如果这是您真正想要做的。

如果hadoop迭代器是可克隆的,理论上可以将其重置为开始。在Mapreduce框架中重置到开头是可以接受的,因为您仍然可以从头开始读取文件,从而获得更好的总体速度。将迭代器重置为随机点将与Mapreduce的思维定势背道而驰,因为它可能需要从文件进行随机访问


在解释为什么他们选择不使迭代器可克隆时有一个问题,尽管它确实表明这是可能的,因为值将必须存储在内存中。

我知道“迭代器”不可重置,但mapreduce函数强制我获取“迭代器”对象,所以我想知道如何才能我解决了这个问题。您总是可以将
迭代器的内容读入
集合
,但这当然意味着您必须同时将所有内容保存在内存中。这对于您的用例来说可能没问题,也可能没问题。您确定不能通过创建多个
Iterable副本来将迭代器重置为开始。迭代器
我模糊地记得这样做过,但我猜您并不是真的对,@aaronman。这个链接非常有助于我理解为什么他们不提供clonable。我认为最好选择你的答案。