《JAVA从入门到??》集合DAY01---Collection

集合概述

集合框架

在这里插入图片描述

集合:集合是java中提供的一种容器,可以用来存储多个数据。集合和数组既然都是容器,它们有啥区别呢?1.数组的长度是固定的,集合的长度是可变的。2.数组中存储的是同一类型的元素,一般存储基本数据类型值。集合存储的都是对象,而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。

JAVASE提供了满足各种需求的API,在使用这些API前,先了解其继承与接口操作架构,才能了解何时采用哪个类,以及类之间如何彼此合作,从而达到灵活应用。
集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection和双列集合java.util.Map。

                              集合框架基础整体结构图

在这里插入图片描述

Collection

单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是java.util.List和java.util.Set。其中,
List的特点是元素有序、元素可重复。
Set的特点是元素无序,而且不可重复。

List接口的主要实现类有java.util.ArrayList、java.util.LinkedList和java.util.Vector
Set接口的主要实现类有java.util.HashSet和java.util.TreeSet。

JDK中提供了丰富的集合类库,为了便于初学者进行系统地学习,接下来通过一张图来描述整个集合类的继承体系。

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

public boolean add(E e):把给定的对象添加到当前集合中 。
public void clear():清空集合中所有的元素。
public boolean remove(E e):把给定的对象在当前集合中删除。
public boolean contains(E e):判断当前集合中是否包含给定的对象。
public boolean isEmpty():判断当前集合是否为空。
public int size():返回集合中元素的个数。
public Object[] toArray():把集合中的元素,存储到数组中。

List接口介绍

java.util.List接口继承自Collection接口,是单列集合的一个重要分支,习惯性地会将实现了 List接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。 看完API,我们总结一下:
List接口特点:

  1. 它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、 22、33的顺序完成的)。
  2. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
  3. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。
    List接口中常用方法:List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,如下:

public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
public E get(int index) :返回集合中指定位置的元素。
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

ArrayList集合

java.util.ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中。当从 ArrayList 的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。由于日常开发中使用最多的功能为查询数据、遍历数据,所以 ArrayList是最常用的集合。许多程序员开发时非常随意地使用ArrayList完成任何需求,并不严谨,这种用法是不提倡的。
常用方法:
add(E e) 将指定的元素追加到此列表的末尾。
add(int index, E element) 在此列表中的指定位置插入指定的元素。
contains(Object o) 如果此列表包含指定的元素,则返回 true 。
get(int index) 返回此列表中指定位置的元素。
isEmpty() 如果此列表不包含元素,则返回 true 。
remove(int index) 删除该列表中指定位置的元素。
set(int index, E element) 用指定的元素替换此列表中指定位置的元素。
size() 返回此列表中的元素数。

LinkedList集合

java.util.LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了 List 接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。LinkedList是一个双向链表,那么双向链表是什么样子的呢,我们用个图了解下:
在这里插入图片描述

实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。这些方法我们作为了解即可:
public void addFirst(E e) :将指定元素插入此列表的开头。
public void addLast(E e) :将指定元素添加到此列表的结尾。
public E getFirst() :返回此列表的第一个元素。
public E getLast() :返回此列表的最后一个元素。
public E removeFirst() :移除并返回此列表的第一个元素。
public E removeLast() :移除并返回此列表的最后一个元素。
public E pop() :从此列表所表示的堆栈处弹出一个元素。
public void push(E e) :将元素推入此列表所表示的堆栈。
public boolean isEmpty() :如果列表不包含元素,则返回true。

Vector集合

Vector与ArrayList 一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问 ArrayList慢。

Iterator接口介绍

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

想要遍历Collection集合,那么就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法:
public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。

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

Iterator接口的常用方法如下:
public E next():返回迭代的下一个元素。
public boolean hasNext():如果仍有元素可以迭代,则返回 true。

代码演示:
//使用迭代器 遍历每个集合对象都有自己的迭代器
Iterator it = coll.iterator();
// 泛型指的是 迭代出 元素的数据类型
while(it.hasNext()){ //判断是否有迭代元素
String s = it.next();//获取迭代出的元素
System.out.println(s);
}

Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,为了让初学者能更好地理解迭代器的工作原理,接下来通过一个图例来演示Iterator对象迭代元素的过程:

原理总结:
在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。

Set接口介绍

java.util.Set 接口和java.util.List 接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比 Collection 接口更加严格了。与 List 接口不同的是, Set 接口中元素无序,没有索引的方法,也不支持普通的for循环遍历,并且都会以某种规则保证存入的元素不出现重复。Set 集合有多个子类,这里我们介绍其中的 java.util.HashSet 、 java.util.TreeSet 这两个集合。
Set集合取出元素的方式可以采用:迭代器、增强for。

Set 注重独一无二的性质,该体系集合用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。对象的相等性本质是对象 hashCode 值(java 是依据对象的内存地址计算出的此序号)判断的,如果想要让两个不同的对象视为相等的,就必须覆盖 Object 的 hashCode 方法和 equals 方法。

HashSet集合

哈希表边存放的是哈希值。HashSet 存储元素的顺序并不是按照存入时的顺序(和 List 显然不同)而是按照哈希值来存的所以取数据也是按照哈希值取得。元素的哈希值是通过元素的hashcode 方法来获取的, HashSet 首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals 方法如果equls结果为 true,HashSet 就视为同一个元素。如果equals为 false 就不是同一个元素。

哈希值相同 equals 为 false 的元素是怎么存储呢,就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希一样的存一列。如图 1 表示 hashCode 值不相同的情况;图 2 表示 hashCode 值相同,但 equals 不相同的情况。
在这里插入图片描述

HashSet 通过 hashCode 值来确定元素在内存中的位置。一个 hashCode 位置上可以存放多个元素。
HashSet存储自定义类型元素:
给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一。

Hash概念

哈希值:哈希值就是一个十进制的整数,就是操作系统随机分配值(也可以理解成对象的地址值,逻辑上的地址值,并不是真正的物理地址。注意哈希值是模拟的)
Object对象中就有hashCode()获取哈希值
User user1 = new User();
User user2 = new User();
System.out.println(user1);//com.gxa.collection.set.User@4554617c
System.out.println(user2);//com.gxa.collection.set.User@74a14482
//调对象的toString()方法
System.out.println(user1 == user2);//内存地址值
System.out.println(“对象的哈希值”);
System.out.println(user1.hashCode());
System.out.println(user2.hashCode());
String str1 = new String(“abc”);
String str2 = new String(“cba”);
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
String str3 = new String(“Aa”);
String str4 = new String(“BB”);
System.out.println(str3.hashCode());
System.out.println(str4.hashCode());
存储元素原理分析
在这里插入图片描述

掌握重要方法,原理:
hashCode() equals()
/**

  • java.util.HashSet,不能存放重复的元素
  •  核心(如何判断元素到底是否重复,规则?),哈希值、equals
    
  • 需求:
  • 如果两个用户的用户名称和密码一样,我就默认为是同一个对象。
    

*/
User user1 = new User(“zhangsan”,“123”);
User user2 = new User(“zhangsan”,“123”);
System.out.println(user1.hashCode());
System.out.println(user2.hashCode());
System.out.println(user1.equals(user2));
//user1和user2到底是不是同一个元素,不是同一个元素
HashSet hashSet = new HashSet();
hashSet.add(user1);
hashSet.add(user2);
System.out.println(hashSet);

TreeSet集合

  1. TreeSet()是使用二叉树的原理对新 add()的对象按照指定的顺序排序(升序、降序),每增加一个对象都会进行排序,将对象插入的二叉树指定的位置。
  2. Integer 和 String 对象都可以进行默认的 TreeSet 排序,而自定义类的对象是不可以的,自己定义的类必须实现 Comparable 接口,并且覆写相应的 compareTo()函数,才可以正常使用。
  3. 在覆写 compare()函数时,要返回相应的值才能使 TreeSet 按照一定的规则来排序
  4. 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

案例演示:

TreeSet<Integer> treeSet = new TreeSet<Integer>();
//默认自然排序机制,注意和HashSet不一样
treeSet.add(1);
treeSet.add(2);
treeSet.add(null);
treeSet.add(3);
treeSet.add(7);
System.out.println(treeSet);
//默认情况,TreeSet中不能直接存放对象,要想存放对象需要进行对象排序规则编写。
//1、内部类方式实现 Comparator,2、实现接口Comparable
User user1 = new User("zhangsan","123",1000);
User user2 = new User("zhangsan","1234",1000);
TreeSet<User> treeSet2 = new TreeSet<User>(new Comparator<User>() {
    @Override
    public int compare(User o1, User o2) {//自己制定排序的规则,返回值需要参考API
        if(o1.getMoney() > o2.getMoney()){
            return -1;
        }
        if(o1.getMoney() < o2.getMoney()){
            return 1;
        }
        return 0;
    }
});
treeSet2.add(user2);
treeSet2.add(user1);
System.out.println(treeSet2);

User user1 = new User("zhangsan","123",1000);
User user2 = new User("zhangsan","1234",2000);
TreeSet<User> treeSet2 = new TreeSet<User>();
treeSet2.add(user2);
treeSet2.add(user1);
System.out.println(treeSet2);

满足规则:
1、无序且不重复(默认内部有自然排序机制)
2、底层采用TreeMap
3、插入相同元素不是覆盖,而是直接不添加。
4、TreeSet中不能添加null
5、没有get()这个方法,因为它是无序的
6、TreeSet不能直接添加对象,因为他无法进行自然排序。java.lang.ClassCastException:com.gxa.am.User cannot be cast to java.lang.Comparable
7、TreeSet如果要进行对象排序,有两种方式可实现:1、内部类方式实现 Comparator,2、实现接口Comparable

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值