Java学习——List集合&Set&Map

目录

集合

主要内容

集合

1、 Collection

1、添加元素

2、删除元素

3、判断

4、获取元素个数

5、交集

6、转为数组

2、 Iterator迭代器

1. Iterator接口API

3. 增强for与Iterable接口

4. modCount与fail-fast机制

3. List集合

1. List接口介绍

1.1 List集合的遍历方式

2. List接口中常用方法

1、添加元素

2、获取元素

3、获取元素索引

4、删除和替换元素

3. ArrayList实现类

4. ListIterator


集合

主要内容

  • List集合

  • Set集合

  • Map集合

集合

集合是java中提供的一种容器,可以用来存储多个对象数据。

既然有数组作为数据容器,Java为什么还提供集合容器?它们有啥区别呢?

  1. 数组的长度是固定的,不利于数据的增删。集合的长度是可变的。

  2. 数组中提供的属性和方法较少,不便于进行常用的增删改查操作,集合提供了更丰富的API。

  3. 数组存储数据的特点单一,即有序的,可重复的。集合有很多种类型,分别有不同的存储特点。

  4. 数组中可以存储基本数据类型值,也可以存储对象,而集合中只能存储对象

集合主要分为两大系列:Collection和Map,Collection 表示一组对象,Map表示一组映射关系或键值对。

1、 Collection

Collection 层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接实现:它提供更具体的子接口(如 Set 和 List、Queue)实现。此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。

Collection<E>是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。方法如下:

1、添加元素

(1)add(E obj):添加元素对象到当前集合中

(2)addAll(Collection<? extends E> other):添加other集合中的所有元素对象到当前集合中,即this = this ∪ other

2、删除元素

(1) boolean remove(Object obj) :从当前集合中删除第一个找到的与obj对象equals返回true的元素。

(2)boolean removeAll(Collection<?> coll):从当前集合中删除所有与coll集合中相同的元素。即this = this - this ∩ coll

(3) void clear(); 清空集合

3、判断

(1)boolean isEmpty():判断当前集合是否为空集合。

(2)boolean contains(Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元素。

(3)boolean containsAll(Collection<?> c):判断c集合中的元素是否在当前集合中都存在。即c集合是否是当前集合的“子集”。

4、获取元素个数

(1)int size():获取当前集合中实际存储的元素个数

5、交集

(1)boolean retainAll(Collection<?> coll):当前集合仅保留与c集合中的元素相同的元素,即当前集合中仅保留两个集合的交集,即this = this ∩ coll;

6、转为数组

(1)Object[] toArray():返回包含当前集合中所有元素的数组

方法演示:

public class Demo {
    public static void main(String[] args) {
        //创建Collection集合
        Collection c = new ArrayList();
        // *1、添加元素 **
        //(1)add(E obj):添加元素对象到当前集合中
        c.add("hello");
        c.add("world");
        c.add("java");
        System.out.println(c);
        //(2)addAll(Collection < ? extends E > other):添加other集合中的所有元素对象到当前集合中,即this = this ∪other
        Collection c2 = new ArrayList();
        c2.add("tom");
        c2.add("jack");
        c2.add("java");
        c.addAll(c2);
        System.out.println(c);

        // *2、删除元素 **
        // (1)boolean remove (Object obj) :从当前集合中删除第一个找到的与obj对象equals返回true的元素。
        c.remove("java");
        // (2)boolean removeAll (Collection < ? > coll):从当前集合中删除所有与coll集合中相同的元素。即this = this - this ∩coll
        c.removeAll(c2);
        //​(3) void clear (); 清空集合
        c.clear();

        // **3、判断 **
        //(1)boolean isEmpty ():判断当前集合是否为空集合。
        System.out.println(c.isEmpty());
        //(2)boolean contains (Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元素。
        System.out.println(c.contains("tom"));
        //(3)boolean containsAll (Collection < ? > c):判断c集合中的元素是否在当前集合中都存在。即c集合是否是当前集合的“子集”。
        System.out.println(c.containsAll(c2));

        //**4、获取元素个数 **
        //(1)int size ():获取当前集合中实际存储的元素个数
        int size = c.size();
        System.out.println(size);

        // **5、交集 **
        //(1)boolean retainAll (Collection < ? > coll):当前集合仅保留与c集合中的元素相同的元素,即当前集合中仅保留两个集合的交集,即this = this ∩coll;
        System.out.println(c.retainAll(c2));

        // **6、转为数组 **
        //(1)Object[] toArray ():返回包含当前集合中所有元素的数组
        Object[] arrays = c.toArray();
        for (int i = 0; i < arrays.length; i++) {
            System.out.println(arrays[i]);
        }
        System.out.println(c);
    }
}

2、 Iterator迭代器

1. Iterator接口API

在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.IteratorIterator接口也是Java集合中的一员,但它与CollectionMap接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。

想要遍历Collection集合,那么就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法:

  • public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。

下面介绍一下迭代的概念:

  • 迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

Iterator接口的常用方法如下:

  • public E next():返回迭代的下一个元素。

  • public boolean hasNext():如果仍有元素可以迭代,则返回 true。

  • public void remove():通过迭代器删除元素

/**
 * Iterator迭代器,用于遍历Collection集合
 */
public class Demo {
    public static void main(String[] args) {
        //创建Collection集合
        Collection c = new ArrayList();
        //添加元素
        c.add("tom");
        c.add("jack");
        c.add("rose");
        c.add("jerry");
        //调用Colletcion集合的iterator方法获取一个迭代器 (使用迭代器遍历集合↓)
        Iterator it = c.iterator(); // Iterator是接口(一种类型)
        //调用Iterator的方法遍历集合
        Object next = it.next();// it.next() == 取出下一个元素
        System.out.println(next);
        System.out.println(it.next());
        System.out.println(it.next());
        System.out.println(it.next());
//        System.out.println(it.next());//NoSuchElementException

        boolean b = it.hasNext();//判断是否有下一个元素
        System.out.println("b = " + b);

        while (it.hasNext()){//判断是否有下一个元素
            Object obj = it.next();//取出下一个元素
            System.out.println(obj);
        }

    }
}
public class Demo2 {
    public static void main(String[] args) {
        //创建Collection集合
        Collection c = new ArrayList();
        //添加元素
        c.add(11);
        c.add(22);
        c.add(55);
        c.add(44);
        c.add(33);
        //遍历集合
        Iterator it = c.iterator();//创建迭代器
        while (it.hasNext()) {//判断是否有下一个元素
            Object obj = it.next();
            System.out.println(obj);
        }
    }
}

3. 增强for与Iterable接口

增强for循环(也称foreach循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。

/**
 * foreach循环,也称为增强for循环:用于遍历数组和collection集合
 * 格式:
 *   for(元素类型 变量: 数组或集合){
 *      //循环体
 *   }
 */
public class Demo {
    //增强for遍历数组
    @Test
    public void test() {
        int[] arr = {11, 22, 33, 44};
        for (int i : arr) {//区别普通for循环,增强for循环的i已经是元素,不在是角标(下标)
            System.out.println(i);//所以直接输出i即可打印值,非arr[i]
        }
    }

    //增强for循环遍历Collection集合:底层实现是Iterator迭代器
    @Test
    public void test1(){
        Collection c = new ArrayList();
        c.add("hello");
        c.add("java");
        c.add("world");
        c.add("abc");
        //遍历集合  快捷写法: c.iter + 回车 , c.for + 回车
        for (Object obj : c) {
            System.out.println(obj);
        }
    }
}

增强for循环可以遍历Iterable接口的实现类:

//自定义类,继承Iterable 
public class Student implements Iterable {
    @Override
    public Iterator iterator() {
        return null;
    }
}
public class Demo2 {
    @Test
    public void test(){
        Student stu = new Student();
        for (Object o : stu) { //Student继承Iterable后重写iterator方法方可调用

        }

    }
}

4. modCount与fail-fast机制

这里举一个小例子,让该知识点更通俗易懂:课代表要查班级中总共有多少学生,从第一位学生开始数数 1 2 3...  ,数到一半的时候班主任叫走了第一位同学,但是此时课代表并不知道已经走了一位同学且还在继续往后计算,最后班长数的结果和实际不同。课代表查询的是原班级总人数,而老师在课代表查询期间改变了班级人数,这就叫并发修改异常。

迭代器的快速失败机制:当使用迭代器遍历集合时,使用迭代器之外的方式修改集合,那么迭代器就会立即抛出(ConcurrentModificationException)并发修改异常 。来阻止这样的操作,以免在将来发生更大问题。  

如何实现的快速失败机制?  

借助集合的一个遍历modCount实现。modCcount记录了集合的修改次数,当创建迭代器时迭代器会记录此时的集合修改次数,   在每次取元素时都会判断集合的修改次数是否有变化,如果有则立即抛异常。

public class Demo {
    @Test
    public void test(){
        Collection c = new ArrayList();
        c.add("tom");
        c.add("jack");
        c.add("rose");
        c.add("jerry");
        //遍历集合并删除指定的一个元素
        Iterator it = c.iterator();
        while (it.hasNext()) {//遍历
            Object obj = it.next();  //java.util.ConcurrentModificationException 并发修改异常
            if ("jack".equals(obj)){//判断是否存在
//                c.remove(obj);//使用集合的删除方法删除元素
                it.remove();//使用迭代器的删除方法,删除当前元素
            }
        }

        //使用增强for遍历集合时不要修改集合
        for (Object o : c) {
            c.remove(o);//java.util.ConcurrentModificationException
        }
        System.out.println(c);
    }
}

3. List集合

我们掌握了Collection接口的使用后,再来看看Collection接口中的子接口,他们都具备那些特性呢?

1. List接口介绍

java.util.List接口继承自Collection接口,是单列集合的一个重要分支,习惯性地会将实现了List接口的对象称为List集合。

List接口特点:

  1. List集合所有的元素是以一种线性方式进行存储的,例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)

  2. 它是一个元素存取有序的集合。即元素的存入顺序和取出顺序有保证。

  3. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。

  4. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

/**
 * List集合
 *  List是一个Collection的典型子接口:
 *  List集合的特点:
 *      1.元素有序,可重复
 *      2.可以通过索引访问元素
 *  Set集合特点:
 *      元素唯一,通常无序。
 *
 *  List接口的特有方法:(都是与索引相关的方法)
 */
public class Demo {
    @Test
    public void test(){
        //创建List集合
        List list = new ArrayList();
        list.add("hello");
        list.add("world");
        list.add("abc");
        System.out.println(list);       //[hello, world, abc]

        //1、添加元素,在指定位置添加新元素
        //* void add(int index, E ele)
        list.add(1, "java");        //[hello, java, world, abc]
        //* boolean addAll(int index, Collection<? extends E> eles) 在指定的位置添加另外一个集合

        //2、获取元素
        //* E get(int index)
        Object obj = list.get(0);
        System.out.println(obj);
        //* List subList(int fromIndex, int toIndex) 截取一个子集合
        List subList = list.subList(0, 2);       // [hello, java]      //截 取0-2位置,包含0 不包含2   【包前不包后】
        System.out.println(subList);

        //3、获取元素索引
        //* int indexOf(Object obj)  获取元素第一次出现的位置
        int index = list.indexOf("java");
        System.out.println("index = " + index);     //index = 1
        //* int lastIndexOf(Object obj)
        int lastIndexOf = list.lastIndexOf("world");
        System.out.println("lastIndexOf = " + lastIndexOf);     //lastIndexOf = 2

        //4、删除和替换元素
        //* E remove(int index)     删除指定位置的元素,返回被删除的元素
        Object remove = list.remove(0);
        System.out.println("remove = " + remove);       //remove = hello  [java, world, abc]
        //* E set(int index, E ele)    修改指定位置的元素,返回被修改的元素
        Object set = list.set(0, "JAVA");
        System.out.println("set = " + set);        //set = java  [JAVA, world, abc]


        System.out.println(list);
    }
}

1.1 List集合的遍历方式

public class Demo2 {
    @Test
    public void test(){
        //创建List集合
        List list = new ArrayList();
        //添加元素
        list.add(11);
        list.add(22);
        list.add(33);
        list.add(44);
        //遍历集合
        //方式一:  迭代器
        Iterator it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //方式二:  增强for
        for (Object obj : list) {
            System.out.println(obj);
        }
        //方式三:  普通for
        for (int i = 0; i < list.size(); i++) {
            Object obj = list.get(i);
            System.out.println(obj);
        }
    }
}

2. List接口中常用方法

List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,如下:

List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来操作集合元素的方法。

1、添加元素

  • void add(int index, E ele)

  • boolean addAll(int index, Collection<? extends E> eles)

2、获取元素

  • E get(int index)

  • List subList(int fromIndex, int toIndex)

3、获取元素索引

  • int indexOf(Object obj)

  • int lastIndexOf(Object obj)

4、删除和替换元素

  • E remove(int index)

  • E set(int index, E ele)

List集合特有的方法都是跟索引相关:

public class Student {
    private String name;
    private  int age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student() {
    }
}
public class Demo3 {
    public static void main(String[] args) {
        //创建List集合
        List list = new ArrayList();
        //添加元素
        Student stu = new Student("tom", 18);
        list.add(stu);
        list.add(new Student("jack", 19));
        list.add(new Student("rose", 18));
        list.add(new Student("jerry", 20));
        list.add(new Student("tom", 18));

        //遍历集合
        //迭代器
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Object obj = it.next();
            System.out.println(obj);
        }
        
        Student student = new Student("tom",18);
        boolean remove = list.remove(student);
        System.out.println("remove = " + remove);
        System.out.println(list);

    }
}

3. ArrayList实现类

ArrayList是List接口的典型实现类,底层使用长度可变的数组实现,常用方法都来自Collection和List接口。

ArrayList因为底层使用了数组存储数据,所以具有查询快,增、删慢的特点。

数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。

逻辑结构:描述元素之间的关联关系

物理结构:存储结构,有一定关系的元素数据如何存储

public class Demo {
    public static void main(String[] args) {
        //创建ArrayList集合
        ArrayList list = new ArrayList();
        list.add("hello");
        list.add("java");
        list.add("world");
        list.add("abc");
        list.add("abc");
        for (Object o : list) {
            System.out.println(o);
        }
    }
}
/**
 * Arrays数组工具类的asList方法,可以快速创建一个List集合,此集合是不可变的
 */

import java.util.Arrays;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        List list = Arrays.asList("hello", "java", "world", "abc");
//        list.add("xxx");//java.lang.UnsupportedOperationException  不支持的操作
        list.remove("java");//java.lang.UnsupportedOperationException
        System.out.println("list = " + list);
    }
}

4. ListIterator

List 集合额外提供了一个 listIterator() 方法,该方法返回一个 ListIterator 对象, ListIterator 接口继承了 Iterator 接口,提供了专门操作 List 的方法:

  • void add():通过迭代器添加元素到对应集合

  • void set(Object obj):通过迭代器替换正迭代的元素

  • void remove():通过迭代器删除刚迭代的元素

  • boolean hasPrevious():如果以逆向遍历列表,往前是否还有元素。

  • Object previous():返回列表中的前一个元素。

  • int previousIndex():返回列表中的前一个元素的索引

  • boolean hasNext()

  • Object next()

  • int nextIndex()

	public static void main(String[] args) {
		List<Student> c = new ArrayList<>();
		c.add(new Student(1,"张三"));
		c.add(new Student(2,"李四"));
		c.add(new Student(3,"王五"));
		c.add(new Student(4,"赵六"));
		c.add(new Student(5,"钱七"));
		
		//从指定位置往前遍历
		ListIterator<Student> listIterator = c.listIterator(c.size());
		while(listIterator.hasPrevious()){
			Student previous = listIterator.previous();
			System.out.println(previous);
		}
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

别晃我的可乐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值