Java集合学习

目录

一、集合概述

迭代器Iterator接口

ListIterator

使用 foreach 循环遍历集合元素


一、集合概述

从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。

迭代器Iterator接口

      Iterator 对象称为迭代器 ( 设计模式的一种 ) ,主要用于遍历 Collection 集合中的元素。
      GOF 给迭代器模式的定义为:提供一种方法访问一个容器 (container) 对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式,就是为容器而生。 类似于“公 交车上的售票员”、“火车上的乘务员”、“空姐”。
      Collection 接口继承了 java.lang.Iterable 接口,该接口有一个 iterator() 方法,那么所有实现了Collection 接口的集合类都有一个 iterator() 方法,用以返回一个实现了Iterator接口的对象。      
       Iterator 仅用于遍历集合 Iterator 本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。

集合元素的遍历操作,使用迭代器Iterator接口
1.内部的方法:hasNext() 和  next()

Iterator iterator = coll.iterator();
//hasNext():判断是否还有下一个元素
while(iterator.hasNext()){
    //next():①指针下移 ②将下移以后集合位置上的元素返回
    System.out.println(iterator.next());
}
在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常。

2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
3.内部定义了remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove()

迭代器的执行原理:

Iterator iterator = coll.iterator();

1.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。

2.//hasNext():判断是否还有下一个元素

3.//next():①指针下移 ②将下移以后集合位置上的元素返回    先指针下移,再返回元素

错误方式一:

    @Test
    public void test(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //错误方式:
        Iterator iterator = coll.iterator();
        while((iterator.next()) != null){
            System.out.println(iterator.next());
        }
    }

结果:

456
Tom

java.util.NoSuchElementException
	at java.util.ArrayList$Itr.next(ArrayList.java:862)
....

错误方式二:

    @Test
    public void test(){

        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //错误方式:
        //集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
        while (coll.iterator().hasNext()){
            System.out.println(coll.iterator().next());
        }
    }

结果:

123
123
123
123
123
123
...
出现死循环...一直打印123

Iterator接口的remove()方法:

    @Test
    public void test(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //删除集合中"Tom"
        Iterator iterator = coll.iterator();
        while (iterator.hasNext()){
//            iterator.remove();
            Object obj = iterator.next();
            if("Tom".equals(obj)){
                iterator.remove();
//                iterator.remove();
            }

        }
        //遍历集合
        iterator = coll.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

注意:

1、Iterator可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。

2、如果还未调用next()或在上一次调用next方法之后已经调用了remove方法,再调用remove都会报IllegalStateException。

ListIterator

ListIterator是一个功能更加强大的, 它继承于Iterator接口,只能用于各种List类型的访问。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator。
ListIterator接口定义如下:

public interface ListIterator<E>extends Iterator<E>

ListIterator可以双向移动,向前或向后。类似于双向链表结构可以左右遍历元素。

列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。

ListIterator 没有当前元素;它的光标位置 始终位于调用 previous() 所返回的元素和调用 next() 所返回的元素之间。长度为 n 的列表的迭代器有 n+1 个可能的指针位置。指针位置如下:

                      Element(0)   Element(1)   Element(2)   ... Element(n-1)
 cursor positions:  ^            ^            ^            ^                  ^

注意,remove() 和 set(Object) 方法不是 根据光标位置定义的;它们是根据对调用 next() 或 previous() 所返回的最后一个元素的操作定义的。 

ListIterator中的常用方法:
1.void add(E e):将指定的元素插入列表(可选操作)。 
2.boolean hasNext():以正向遍历列表时,如果列表迭代器有多个元素,则返回true
(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。 
3.boolean hasPrevious():如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。 
4.E next():返回列表中的下一个元素。 
5.int nextIndex():返回对next的后续调用所返回元素的索引。 
6.E previous():返回列表中的前一个元素。 
7.int previousIndex():返回对previous的后续调用所返回元素的索引。 
8.void remove():从列表中移除由next或previous返回的最后一个元素(可选操作)。
9.void set(E e):用指定元素替换next或previous返回的最后一个元素(可选操作)。

示例:

import java.util.*;

public class ListIteratorTest {

    public static void main(String[] args) {
		ArrayList<String> a = new ArrayList<String>();
		a.add("aaa");
		a.add("bbb");
		a.add("ccc");
		System.out.println("原集合: " + a);
		ListIterator<String> it = a.listIterator();
		while (it.hasNext()) {
			System.out.println(it.next() + ", " + it.previousIndex() + ", " + it.nextIndex());
		}
		while (it.hasPrevious()) {
			System.out.print(it.previous() + " ");
		}
		System.out.println();
		//调用listIterator(n)方法
		//创建一个一开始就指向列表索引为n的元素处的ListIterator。
        it = a.listIterator(1);
		while (it.hasNext()) {
			String t = it.next();
			System.out.println(t);
			if ("ccc".equals(t)) {
				it.set("nnn");
			} else {
				it.add("kkk");
			}
		}
		System.out.println("现集合: " + a);
	}
}

结果:

原集合: [aaa, bbb, ccc]
aaa, 0, 1
bbb, 1, 2
ccc, 2, 3
ccc bbb aaa 
bbb
ccc
现集合: [aaa, bbb, kkk, nnn]

Iterator和ListIterator区别
我们在使用List,Set的时候,为了实现对其数据的遍历,我们经常使用到了Iterator(迭代器)。使用迭代器,你不需要干涉其遍历的过程,只需要每次取出一个你想要的数据进行处理就可以了。但是在使用的时候也是有不同的。List和Set都有iterator()来取得其迭代器。对List来说,你也可以通过listIterator()取得其迭代器,两种迭代器在有些时候是不能通用的,Iterator和ListIterator主要区别在以下方面:

(1)ListIterator有add()方法,可以向List中添加对象,而Iterator不能
(2)ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
(3)ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
(4)都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。

因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。

使用 foreach 循环遍历集合元素

1、Java 5.0 提供了 foreach 循环迭代访问 Collection和数组。

2、遍历操作不需获取 Collection 或数组的长度,无需使用索引访问元素。
3、遍历集合的底层调用Iterator完成操作。

Java集合笔记

 1.集合和数组的区别?
   数组的长度固定,工作中不用。集合长度没有限制,工作中常用,工作中只用集合。
2.java中集合一共有几个?
    面试可能会问:给我说一个Java常见的数据结构

   java中集合共有四个,并且所有的集合都是接口。
   其中collection是list和set接口的父接口。此外还有一个单独存在的map接口。
3.collection集合的特点?(重点)
   (1).无序(集合中存储的元素没有索引)
   (2).值可重复

--泛型:规定了集合所能容纳的数据类型(引用数据类型)

4.collection集合中的常用方法?
   (1).add方法:向集合中添加一条数据
   (2).remove方法:删除集合中的一条数据
   (3).size方法:返回集合中元素的个数
   (4).clear方法:移除集合中所有的元素
   (5).isEmpty方法:判断集合是否为空
5.如何从collection集合中取数据?
   (1).所有的集合都可以通过直接打印,显示集合中所有的数据
   (2).foreach循环
   (3).迭代器:迭代器是jdk1.0版本开始时从集合中取出元素的一种方式,非常的古老,是foreach循环的前身,现在工作中基本不用,是面试的考点。
          Iterator<String> it = coll.iterator();
        //iterator方法返回了一个迭代器对象,帮助我们从集合中取数据
        while (it.hasNext()) {
            //hasNext方法:判断集合中是否有元素
            System.out.println(it.next());
            //next方法:将集合中的某个元素取出
6.list集合的特点?(重点)
   (1).有序
   (2).值可重复
7.list集合中常用的方法?
   (1).add方法:向集合中添加一条数据,或者也可以向指定位置添加数据
   (2).remove方法:可以根据下角标或者元素的值来进行删除
   (3).set方法:list集合中独有的方法,可以根据下角标修改元素的值
   (4).get方法:可以根据下角标,取得集合中指定位置的元素
8.list接口常用的实现类?
   (1).arraylist
   (2).linkedlist
   (3).vector:vector底层是数组,jdk1.0版本就有,特别古老,线程安全,速度慢,工作中几乎不用,面试考点。
9.arraylist和linkedlist的区别?(重点)
   (1).arraylist底层是数组结构,linkedlist底层是双端链式结构
   (2).我们在向集合中间位置插入或者删除一条数据时,arraylist慢,linkedlist快
   (3).我们在查询时,arraylist快,linkedlist慢
10.set集合的特点?(重点)
   (1).无序
    (2).值不可重复
11.set集合的常用实现类?
   (1).hashset
    (2).treeset
12.hashset和treeset的区别?(重点:面试可能问,不考)
   hashset:元素在存入集合时无序,取出时也无序
   treeset:元素在存入集合时会将元素按照从小到大排序,取出时有顺序
13. Set集合如何判断添加进来的数据是否重复?
    (1).第一步:调用hashCode方法计算所有对象的哈希玛值,如果相等执行下一步,如果不相等,则认为对象不重复
    (2).第二步:调用equals方法,如果结果为true则认为对象重复,不允许添加到set集合中,否则可以正常添加

14. 如何将具有相同成员变量的对象,不能重复添加到set集合中?
    重写hashCode和equals方法
    换言之:Set集合中装对象时,一般情况下必须保证对象所在的类要重写hashCode和equlas方法
15. 重写compareTo方法的目的?
    目的:判断对象的大小
    对象装到TreeSet集合中时,集合会调用compareTo方法对元素进行排序,所以必须保证装到TreeSet集合中的对象所在的类要实现Comparable接口并重写compareTo方法

16.map集合的特点?
   (1).无序
   (2).元素以键值对的形式存储在map集合中
17.map集合中,键和值的特点?(重点)
   键:无序,不可重复
   值:无序,可重复
18.如果向map集合中添加了相同的键,则后一个值会将前一个值覆盖掉(重点,考点)
19.如何从map集合中取值?
   keyset方法:取出集合中所有的键,返回的是set集合
   values方法:取出集合中所有的值,返回的是collection集合
20.map集合的常用实现类?
   (1).hashmap
   (2).treemap
   (3).hashtable
21.hashmap和hashtable的区别?(考点,面试重点)
   (1).hashmap可以将null当作键或值,hashtable不允许键和值出现null
   (2).hashtable特别古老,线程安全,特别慢,工作中不用

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杀神lwz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值