JAVA学习笔记--迭代器

  迭代器(Iterator)是一种设计模式。它是一个对象,它的工作是遍历并选择序列中的对象,而客户端程序员不必知道或关心该序列底层的结构。创建迭代器的代价小,因而迭代器通常被称为轻量级对象。

一、Iterable

  接口Iterable<T>,是Collection<E>等接口的超级接口。实现这个接口允许对象成为 foreach 语句的目标。

import java.util.iterator;

public interface Iterable<T>{

    Iterator<T> iterator();    // 返回一个在一组T类型的元素上进行迭代的迭代器  

}

 

二、Iterator

  接口Iterator<E>,是对Collection进行迭代的迭代器。

  方法:Iterator<E> iterator();         // 返回在此collection元素上进行迭代的迭代器,元素返回的顺序没有保证

  JAVA的Iterator只能单向移动。使用方法iterator()要求容器返回一个在该collection上进行迭代的迭代器,Iterator将准备好返回序列中的第一个元素。

package com.tongye.iterator;

import java.util.*;

public class IteratorExample {
    public static void main(String[] args){
        List<String> list = new ArrayList<String>();    // 创建一个接收String类型元素的列表
        list.add("my");                         // 向list中添加元素
        list.add("name");
        list.add("is");
        list.add("tongye");
        System.out.println(list);               // 打印列表        
        Iterator iter = list.iterator();        // 调用iterator()方法返回一个在list上进行迭代的迭代器        
        while(iter.hasNext()){                  // 用hasNext()方法判断列表中是否还有元素
            System.out.println(iter.next());    // 用next()方法返回迭代器迭代的下一个元素
            iter.remove();                      // 用remove()方法删除迭代器返回的最新的一个元素
        }
        System.out.println(list);               // 打印列表    
    }
}

/* output:
[my, name, is, tongye]
my
name
is
tongye
[]
*/

  可以看到,迭代器可以遍历并选择序列中的对象,这看起来和foreach语句很像,而所有的collection都可以用foreach来遍历。当我们只是需要向前遍历collection而不需要修改collection本身时,foreach语法会显得比较实用,但如果我们需要在遍历期间修改collection,像是删除操作,则不能用foreach语法,会抛出异常,因为在使用for循环的期间调用remove()的话会改变 list.size(),从而导致了错误。这时,使用迭代器进行遍历会比较好。

  当然,迭代器的功能不仅仅只是遍历。迭代器能够将遍历序列的操作与序列底层的结构分离,达到很好的解耦效果,因此,我们也说:迭代器统一了对容器的访问方式。下面用一个例子演示一下迭代器的这个功能:

package com.tongye.iterator;

import java.util.*;

public class IteratorExample {
    // printIterator方法用一个对一组String类型元素进行迭代的迭代器作为形参,方法体对迭代器进行遍历,
    // 这是所有对String类型元素进行迭代的迭代器都可以使用的功能,而且代码是完全相同的
    public static void printIterator(Iterator<String> iter){    
        while(iter.hasNext()){                            // 判断迭代器是否还有元素
            System.out.print(iter.next() + " ");        // 打印迭代器迭代的下一个元素
        }
        System.out.println();
    }
    
    public static void main(String[] args){
        List<String> list = new ArrayList<String>();    // 创建一个接收String类型元素的列表
        list.add("my");                                    // 向list中添加元素
        list.add("name");
        list.add("is");
        list.add("tongye");
        printIterator(list.iterator());                    // list.iterator()返回一个对list进行迭代的迭代器
        
        Set<String> set = new HashSet<String>();        // 创建一个接收String类型元素的set
        set.add("my");                                    // 向set中添加元素
        set.add("name");
        set.add("is");
        set.add("tongye");
        printIterator(set.iterator());
        
        Queue<String> queue = new LinkedList<String>();    // 创建一个接收String类型元素的队列
        queue.add("my");                                // 向queue中添加元素
        queue.add("name");
        queue.add("is");
        queue.add("tongye");
        printIterator(queue.iterator());
    }
}

/* output:
my name is tongye 
tongye name is my 
my name is tongye 
*/

  可以看到,迭代器只负责遍历工作,而不关系序列是什么类型的,这样带来的好处是程序条理更为清晰,代码更为简洁。

 

三、ListIterator

  ListIterator, 系列表迭代器,是Iterator的子类型,只能用于访问List类,但是功能更为强大。允许程序按任一方向遍历列表,迭代期间修改列表,并获得迭代器在列表中的当前位置。ListIterator没有当前元素,它的光标位置始终位于调用previous()所返回的元素和调用next()所返回的元素之间。

1)Iterator只能单向移动,但是ListIterator可以双向移动;

2)可以产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引;

3)可以使用set()方法替换掉它访问过的最后一个元素。

下面的例子简单介绍了一下ListIterator的使用:

package com.tongye.iterator;

import java.util.*;

public class IteratorExample {
    
    public static void main(String[] args){
        Random rand = new Random(47);        
        List<String> list = new ArrayList<String>();       // 创建一个接收String类型元素的列表
        list.add("my");                                    // 向list中添加元素
        list.add("name");
        list.add("is");
        list.add("tongye");
        
        ListIterator<String> iter = list.listIterator();    // 创建一个ListIterator
        iter.add("hello");                                 // 在迭代期间调用add()方法插入元素
        while(iter.hasNext()){                              // hasNext()方法,正向遍历,如果list中还有元素,则返回true
            System.out.print(iter.nextIndex() + ":");      // nextIndex()方法,返回对next的后续调用所返回元素的索引
            System.out.print(iter.next() + " ");    
        }
        System.out.println();
        
        while(iter.hasPrevious()){                          // hasPrevious()方法,逆向遍历,如果list中还有元素,则返回true
            System.out.print(iter.previousIndex() + ":");   // previousIndex()方法,返回对previous的后续调用所返回元素的索引
            System.out.print(iter.previous() + " ");        
        }
        System.out.println();
        
        while(iter.hasNext()){
            iter.next();
            iter.set(list.get(rand.nextInt(4)));            // set()方法,用指定元素替换next或previous返回的最后一个元素
        }
        System.out.println(list);
    }
}

/* output:
1:my 2:name 3:is 4:tongye 
4:tongye 3:is 2:name 1:my 0:hello 
[name, my, name, name, name]
* */

  关于add()方法,用下面这张图来说明一下:ListIterator.add()方法可以在迭代期间向列表中添加元素,元素添加的位置是当前光标所在位置之前(next()所返回的下一个元素之前(如果有),previous()所返回的下一个元素之后(如果有))。因此,用add()添加一个元素,并不会影响插入的这一次遍历中对next()的后续调用,因此在上面的程序,第一次调用next()方法并没有输出添加的元素 hello;但是会对previous的后续调用有影响,添加的这个元素将是previous后续调用的第一个元素。

  关于 ListIterator.set()方法,可以用指定元素替换 next 或 previous 返回的最后一个元素(可选操作),只有在最后一次调用 next 或 previous 后既没有调用ListIterator.add() 也没有调用 ListIterator.remove()是才可以进行该调用。

 

转载于:https://www.cnblogs.com/tongye/p/6731111.html

深度学习是机器学习一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值