JAVA入门-集合类

在学习集合类之前我们要知道什么是数据结构

数据结构

1.数据结构是计算机存储、组织数据的方式。
2.数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
3.精心选择的数据结构可以带来更高的运行或者存储效率。

一、线性表

①顺序表

一个线性表是n个具有相同特性的数据元素的有限序列。

②链表

链表里面节点的地址不是连续的,是通过指针连起来的。
链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

二、哈希表

链表和数组的结合体
就是找到一种数据内容和数据存放地址之间的映射关系。
把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。
散列法
元素特征转变为数组下标的方法。
散列表的查找步骤
当存储记录时,通过散列函数计算出记录的散列地址
当查找记录时,我们通过同样的是散列函数计算记录的散列地址,并按此散列地址访问该记录

hash表的优缺点

优点
不论哈希表中有多少数据,查找、插入、删除(有时包括删除)只需要接近常量的时间即0(1)的时间级。实际上,这只需要几条机器指令。
哈希表运算得非常快,在计算机程序中,如果需要在一秒种内查找上千条记录通常使用哈希表(例如拼写检查器)哈希表的速度明显比树快,树的操作通常需要O(N)的时间级。哈希表不仅速度快,编程实现也相对容易。
如果不需要有序遍历数据,并且可以提前预测数据量的大小。那么哈希表在速度和易用性方面是无与伦比的。
缺点
它是基于数组的,数组创建后难于扩展,某些哈希表被基本填满时,性能下降得非常严重,所以程序员必须要清楚表中将要存储多少数据(或者准备好定期地把数据转移到更大的哈希表中,这是个费时的过程)。

hash表的原理

1,对对象元素进行哈希算法的运算,并得出一个具体的算法值,这个值 称为哈希值。
2,哈希值就是这个元素的位置。
3,如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 +1顺延。

三、数组

所谓数组,是有序的元素序列。
1.数组
优点:(1)随机访问效率高(根据下标查询),(2)搜索效率较高(可使用折半方法)。
缺点:(1)内存连续且固定,存储效率低。(2)插入和删除效率低(可能会进行数组拷贝或扩容)。
2.链表
优点:(1)不要求连续内存,内存利用率高,(2)插入和删除效率高(只需要改变指针指向)。
缺点:(1)不支持随机访问,(2)搜索效率低(需要遍历)。
3.Hash表
优点:(1)搜索效率高,(2)插入和删除效率较高,
缺点:(1)内存利用率低(基于数组),(2)存在散列冲突。

集合类

一、泛型

泛型则是规定了某个集合只可以存放特定类型的对象的引用,会在编译期间进行类型检查,可以直接指定类型来获取集合元素
注:
1 泛型集合中的限定类型,不能使用基本数据类型
2 可以通过使用包装类限定允许存放基本数据类型

二、哈希值

1 就是一个十进制的整数,有操作系统随机给出
2 可以使用Object类中的方法hashCode获取哈希值
3 Object中源码: int hashCode()返回该对象的哈希码值;

三、二叉树

自己去找别人的博客学

四、红黑树

自己去找别人的博客学

五、迭代器

(增强for的底层原理也是迭代器)
容器中常用到,迭代器就是用来遍历集合的!
Collection集合元素的通用获取方式:
在取出元素之前先判断集合中有没有元素。如果有,就把这个元素取出来,继续再判断,如果还有就再取出来,一直把集合中的所有元素全部取出来,这种取出元素的方式专业术语称为迭代。

①.Iterator

java中Iterator为一个接口,它只提供了迭代的基本规则。
这是一个Collection中的抽象方法,所有的子类都实现了这个方法并且返回了Iterator对象。
举例

package java.util;
public interface Iterator<E> {
    boolean hasNext();//判断是否存在下一个对象元素
    E next();//获取下一个元素
    void remove();//移除元素
}

注意:在使用Iterator时,禁止对所遍历的容器进行改变大小操作。

②.Spliterator

Spliterator是1.8新增的迭代器,属于并行迭代器,可以将迭代任务分割交由多个线程来进行。
分别交于不于的线程去遍历,可以提高效率。

③.ListIterator

ListIterator是一个更强大的Iterator子类型,能用于各种List类访问,
ListIterator可以往前遍历,添加元素,设置元素

Iterator和ListIterator的区别:
两者都有next()和hasNext(),可以实现向后遍历,但是ListIterator有previous()和hasPrevious()方法,即可以实现向前遍历
ListIterator可以定位当前位置,nextIndex()和previous()可以实现
ListIterator有add()方法,可以向list集合中添加数据
都可以实现删除操作,但是ListIterator可以实现对对象的修改,set()可以实现,Iterator仅能遍历,不能修改

④.forEach()

使用接收lambda表达式的forEach方法进行快速遍历.

List<String> strs = Arrays.asList("a", "b", "c"); 
  // 使用Java 1.8的lambda表达式 strs.forEach(out::println);

集合类的作用

集合类也叫做容器类,和数组一样,用于存储数据
数组
1.数组类型单一,并且长度固定,限制性很大。
集合类
1.集合类可以动态增加长度
2.集合存储的元素都是对象(引用地址),所以集合可以存储不同的数据类型,集合类的都在java.util下。

集合框架体系的组成

集合框架体系是由Collection、Map(映射关系)和Iterator(迭代器)组成

①Collection体系

把集合共性的内容不断往上提取,最终形成集合的继承体系---->Collection
并且所有的Collection实现类都重写了toString()方法.
Set(集): 元素是无序的且不可重复。
List(列表):元素是有序的且可重复。
Queue(队列):封装了数据结构中的队列。

②Map体系

Map用于保存具有映射关系的数据,即key-value(键值对)。
Map集合的key是唯一的,不可重复,而value可以重复。所以一个value可以对应多个key

③迭代器体系

集合的接口与类

①集合的终极爸爸类collection

Collection是最基本的集合接口;
由Collection接口派生的两个接口是List和Set。
Collection接口常用的子接口有List 接口和Set接口

②List

是collection的一个子接口。
List:
1.有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。
2.元素可以重复。
优点:
操作读取操作效率高,基于数组实现的,可以为null值,可以允许重复元素,有序,异步。
缺点:
由于它是由动态数组实现的,不适合频繁的对元素的插入和删除操作,因为每次插入和删除都需要移动数组中的元素。

③ArrayList

是接口List的一个实现类。
ArrayList
是基于数组实现的一个动态数组,也是一个对象。
底层
底层是一个Object[]
特点
可以为null
ArrayList默认元素追加到数组后面,
查看任意位置元素只需要获取当前位置的下标的数组就可以,效率很高
ArrayList 查询快,增删慢。
Arraylist存放在堆内存中。
ArrayList线程不安全的。
在ArrayList的 中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;
允许存放重复数据,存储时按照元素的添加顺序存储
ArrayList的遍历方法
1.

// 第一种遍历方法
System.out.println("第一种遍历方法普通for循环");
for (int i = 0; i < list.size(); i++) {
Student s = list.get(i);
System.out.println("姓名:" + s.getName() + "年龄" + s.getAge());
        }
//    第二种遍历方法
        System.out.println("第二种遍历方法iterator");
        Iterator<Student> it = list.iterator();// 返回一个迭代器
        while (it.hasNext()) {
            Student s = it.next(); // 返回迭代器的下一个元素
            System.out.println("姓名:" + s.getName() + "年龄" + s.getAge());
        }

//        第三种遍历方法    

        System.out.println("第三种遍历方法foreach");
        for (Student s : list) {
            System.out.println("姓名:" + s.getName() + "年龄" + s.getAge());
        }

    }

最简单也是最常见的就是第三种 Lambda表达式foreach()

-----------------------重点分割线--------------------------------------
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

④Set

是collection的一个子接口。

底层:
set的底层是map集合

特点
1.无序(存入和取出顺序有可能不一致),
2.不可以存储重复元素。
3.必须保证元素唯一性。加入Set的元素必须定义equals()方法以确保对象的唯一性。
–怎么理解这里的无序?–
【Set 的实现类都有一套自己的排序算法,每添加一个元素,都会按照其内部算法将元素添加到合适的位置,所以不能保证内部存储是按元素添加的顺序而存储的。】

Set的遍历方式
set集合没有索引,只能用迭代器或增强for循环遍历

  1. Iterator的方法:

boolean hasNext() : 判断是否存在下一个可访问的元素。
Object next() : 返回要访问的下一个元素

Set接口中的常用方法:
1.boolean add (E e )
如果set中尚未包含指定元素,则添加指定元素。
2.void clear ()
从此set中移除所有的元素。
3.boolean contains( Object o)
如果此 set包含指定元素 ,则返回true。
4.boolean remove( Object o)
如果指定元素存在于此set中,则将其移除。
5.int size()
返回此set中的元素的数量(set的容量)。

⑤map

是与collection齐头并进的另一接口
底层:
底层是一个哈希表(数组+单向链表)
查询快,增删快, 是一个无序集合
因此不允许键重复,但允许值重复。
特点
1.无序(存入和取出顺序有可能不一致),

Map接口中的常用方法:
1.get(key) 根据key值返回对应的value值,key值不存在则返回null
2.put(key , value); 往集合中添加元素(key和value)
  注意:添加的时候,如果key不存在,返回值null
  如果Key已经存在的话,就会新值替换旧值,返回旧值
3. remove(key); 删除key值对应的键值对;如果key不存在 ,删除失败。返回值为 null,如果key存在则删除成功,返回值为删除的value
Map遍历方式
第一种方式:通过key找value的方式:
   Map中有一个方法:
      Set keySet(); 返回此映射包含的键的Set 集合
   操作步骤:
   1.调用Map集合的中方法keySet,把Map集合中所有的健取出来,存储到Set集合中
   2.遍历Set集合,获取Map集合中的每一个健
   3.通过Map集合中的方法get(key),获取value值
    可以使用迭代器跟增强for循环遍历
第二种方式:Map集合遍历键值方式
    Map集合中的一个方法:
    Set<Map.Entry<k,v>> entrySet(); 返回此映射中包含的映射关系的Set视图
 使用步骤
    * 1.使用Map集合中的方法entrySet,把键值对(键与值的映射关系),取出来存储到Set 集合中
    * 2.遍历Set集合,获取每一个Entry对象
    * 3.使用Entry对象中的方法getKey和getValue获取健和值
  可以使用迭代器跟增强for循环遍历

⑥hashSet

实现了set接口
底层
底层数据结构是包装过的hashmap最底层也就是哈希表,
特点
线程是不同步的 。
存储取出都比较快
不能保证元素的排列顺序
集合元素可以是null

⑦hashMap

是Map接口的实现
底层
底层是哈希表
特点
1.最多只允许一条记录的键为Null;允许多条记录的值为 Null。
2.根据键可以直接获取它的值,具有很快的访问速度。遍历时,取得数据的顺序是完全随机的。
3.不支持线程的同步
4.是无序的。

⑧hashtable

底层
哈希表
特点
1.线程安全
2.低效
3.不支持null
4.支持线程同步
5.每个元素是一个key-value对

Hashtable 是线程安全的集合,是单线程的,运行速度慢
    HashMap 是线程不安全的集合,是多线程的,运行速度快

(其他内容在你真正入门后再学)
     ------完------

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值