Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 构建自定义迭代器_Java_Iterator_Hashmap - Fatal编程技术网

Java 构建自定义迭代器

Java 构建自定义迭代器,java,iterator,hashmap,Java,Iterator,Hashmap,我正在制作这个类,它是一个基于散列映射的自定义映射。我有一个add方法,如果添加一个对象,该对象将是键,如果该对象当前不在列表中,其值将为1。但是,如果添加当前在列表中的对象,其值将增加1。所以如果我加上10个相同的字符串,键就是那个字符串,值就是10。我理解在实践中,当我迭代映射时,实际上只有一个对象需要迭代,但是,我试图创建一个内部类,该类将定义一个迭代器,该迭代器将迭代同一对象,无论其值是多少倍。我可以通过简单地使用for循环构造一个适当的ArrayList并为此创建一个迭代器来实现这一点

我正在制作这个类,它是一个基于散列映射的自定义映射。我有一个add方法,如果添加一个对象,该对象将是键,如果该对象当前不在列表中,其值将为1。但是,如果添加当前在列表中的对象,其值将增加1。所以如果我加上10个相同的字符串,键就是那个字符串,值就是10。我理解在实践中,当我迭代映射时,实际上只有一个对象需要迭代,但是,我试图创建一个内部类,该类将定义一个迭代器,该迭代器将迭代同一对象,无论其值是多少倍。我可以通过简单地使用for循环构造一个适当的ArrayList并为此创建一个迭代器来实现这一点,但这太低效了。有没有一种简单或更有效的方法可以做到这一点?

您可以使用两个变量:

private T nextObj = null;
private int times = 0;

T next(){
    if(times==0){
        // get the next object and set the times variable to it's value in the hashmap
    }
    times--;
    return nextObj;   
}
您可以从collections API使用。这将创建一个只有一个引用的列表,因此它将是高效的。然后返回
列表
s迭代器。不需要创建内部类

假设
Map
实例变量称为Map,则可以执行以下操作:

Iterator<String> customIteratorForKey(String key) {
    return Collections.nCopies(map.get(key), key).iterator();
}
Iterator customIteratorForKey(字符串键){
返回Collections.nCopies(map.get(key)、key.iterator();
}

听起来像是在实现一个:一个计算每个唯一元素的集合。由于这是一个学校项目,我将给出一些如何做的建议,而不是提供代码。试试你的运气吧,如果你被卡住了,可以改进你的问题

当我创建一个使用另一个集合的新集合类型时,我通常在构建迭代器时做同样的事情

  • Bag.Iterator
    的构造函数将使用
    Map
    中的迭代器初始化自身
  • 正如上面的dtech所示,迭代器需要跟踪它正在计数的当前对象以及它应该返回它的次数
  • next()
    需要在开始时以及当前对象用完计数后获取下一个对象
  • hasNext()
    必须在不实际减少计数或抓取下一个对象的情况下执行相同的操作

  • 我终于明白了。这是我的解决办法。感谢所有回应我并给我指点的人

        private int times = 0;
        private boolean flag = true;
    
        Iterator<Entry<T, Integer>> it = Bag.entrySet().iterator();
        private Entry<T, Integer> t = it.next();
        private int value = t.getValue();
        private T nextObj = t.getKey();
    
        public boolean hasNext() {
            if (times > 0) {
                return true;
            }
            return it.hasNext();
        }
    
    
        public T next() {
            if (this.hasNext() == false) {
                throw new NoSuchElementException();
            }
            if (times == 0 && flag == true) {
                times = value;
                flag = false;
            }
            if (times == 0 && flag == false) {
                t = it.next();
                value = t.getValue();
                nextObj = t.getKey();
                times = value;
            }
            times--;
            return nextObj;
        }
    
    private int times=0;
    私有布尔标志=true;
    迭代器it=Bag.entrySet().Iterator();
    私有条目t=it.next();
    private int value=t.getValue();
    private T nextObj=T.getKey();
    公共布尔hasNext(){
    如果(次数>0){
    返回true;
    }
    返回它。hasNext();
    }
    公共交通工具{
    if(this.hasNext()==false){
    抛出新的NoTouchElementException();
    }
    if(times==0&&flag==true){
    时间=价值;
    flag=false;
    }
    if(times==0&&flag==false){
    t=it.next();
    value=t.getValue();
    nextObj=t.getKey();
    时间=价值;
    }
    时代--;
    返回nextObj;
    }
    
    我不知道你对nextObj做了什么。请解释一下这个变量好吗?它只是对迭代器要返回的下一个对象的引用。因此,不要说“返回某物”,而是说“nextObj=something”。如果您还没有构建自己的迭代器,您可以定义一个迭代器,然后使用映射的迭代器的next()来填充nextObj。实际上,我必须使用一个扩展迭代器的内部类,因为这是一个学校项目:/