集合框架

集合框架

集合:简单的说,集合就是一种容器。

集合作为一种容器,里面可以存放内容,存放的每个内容称为是元素(element)。

在整个集合框架里一共有2个大类容器:Collection和Map

Collection容器(interface)

Collection是元素类容器的根接口

什么是容器

容器是一个用于存放东西的物件。

容器应该具备什么功能呢?(什么样的物件叫容器)
  1. 可以存东西

    add(E element) //往容器里添加一个元素。元素可以是任意类型(整数,字符串,自定义类,容器)

    addAll(Collection c) //往容器里添加多个元素。参数是一个容器,这个方法会把容器里的元素逐一添加进来

  2. 查看

    size() //查看容器中包含多少元素

    contains(Object o) //查看是否包含某个元素

    containsAll(Collection c) //查看是否包含某些元素

    isEmpty() //是不是一个空容器

  3. 可以提取(删除)东西

    clear() //清空容器

    remove(Object o) //移除一个元素

    removeAll(Collection c) //移除参数容器中包含的元素

  4. 其他

    equals(Collection c) //判断是否个另外一个容器相等。

    toArray() //把容器转换为数组

List(interface)

list的英文含义是:列表。

list用于定义什么是有序容器。有序容器是容器的一种。

List是一个接口,它有一个父接口Collection。List相比于Collection多了下标的概念。用标可以去访问元素。

围绕下标提供了一堆方法:

  1. 添加元素

    add(int index, E element) //在指定的位置添加一个元素
    addAll(int index, Collection c) //在指定的位置添加多个元素

    删除元素

    remove(int index) //移除指定位置的元素

  2. 获得子列表

    subList(int fromIndex, int toIndex) //获取一个子列表 [formIndex, toIndex)

  3. 更新元素

    set(int index, E element)// 把指定下标的元素更新为指定内容

  4. 获取元素的位置

    indexOf(Object o) //获取指定元素的下标(正着查)

    lastIndexOf(Object o)//获取指定元素的下标(倒着查)

    get(int index) //获取指定下标的元素

List的实现类

ArrayList

ArrayList是List的实现类。既然是实现类,说明ArrayList实现了List中定义的所有方法。

  1. 如何创建一个ArrayList对象

    ArrayList() //创建一个初始容量为10的列表。列表里尚未存放任何元素。

    ArrayList(int capacity) //创建一个指定初始容量的列表。列表里尚未存放任何元素

    初始容量: 列表刚创建时给定的容量。

    Collection是个容器,这个容器与之前学过的数组不同,数组是定长的容器,不能减少容量也不能增加容量。但是Collection是一个变长的容器,空间不够的时候可以扩容。

    ArrayList(Collection c) //创建一个包含参数中全部元素的列表。

  2. ArrayList的使用

    增删改查(API参考 List)

在创建ArrayList的时候必须指定元素的类型。例如:ArrayList

一旦指定ArrayList存放什么类型的数据,以后取元素的时候,无需进行类型转换。

  1. 遍历ArrayList

    假定ArrayList内容如下:

ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");

遍历ArrayList的方法有很多,常用方式如下:

一、使用for循环遍历

for(int i = 0; i < list.size(); i++){
    String str = list.get(i);
    System.out.println(str);
}

使用list.size()获取元素个数, 从下标0开始循环到结束。通过list.get(i) 获取每个元素,达到遍历的效果。

二、使用迭代器遍历(推荐)

Iterator<String> it = list.iterator();//获取迭代器(迭代器会包含list中所有的元素)
while(it.hasNext()){
    String str = it.next();//获取迭代器中的元素,next执行完,迭代器会指向下一个元素。
    System.out.println(str);
}

Iterator是一个接口,规定了迭代器应该具有什么功能(hasNext(), next(), remove())。

hasNext()方法:用于查看是否还有元素。如果迭代器中还有元素,返回true,如果没有元素了,返回false。

next():获取当前迭代的元素,迭代器指向下一个元素。

remove(): 删除当前迭代到的元素。

三、使用for…each遍历元素

for(String str : list){
    System.out.println(str);//str就是被遍历到的元素。
}

for…each是for循环的增强版,有些语言叫for…in

for…each的本质是通过迭代器遍历元素。可通过XJad反编译工具反编译.class文件查看源码。

ArrayList的优势和劣势

ArrayList的底层实现是数组,数组最大特点:数据的内存空间是连续的,所以根据下标查找元素是非常非常快。

弊端增加和删除慢,如果要删除下标为0的元素,实际上是通过循环,把下标为1的赋值给下标为0,把下标为2的赋值给下标为1的,以此类推,直到所有元素位置正确。

如果要在下标为0的位置添加一个元素,它也是通过循环实现的,最大下标的元素赋值给最大下标加1的位置,第2大的下标的元素赋值给最大下标,以此类推第0个元素赋值给第1个元素,新元素覆盖下标为0的元素。

List的另外一个实现类 LinkedList

LinkedList使用方式同ArrayList。

LinkedList与ArrayList不同,LinkedList底层靠的是双向链表在存储数据。

链表的特点:增删快,查询慢(需要遍历)。

List的另外一个实现类 Vector

实现方式和ArrayList几乎一模一样,Vector所有的方法是线程安全的。在线程里,如果不同的线程在访问同一个List(Vector),不会出现数据紊乱(内部加了锁,一个方法执行的时候,其他的方法等待,执行完以后,其他方法才开始执行)。因为考虑的安全性,不断的加锁和解锁,所以效率很低,速度很慢。

如何选择使用哪个List实现类?

  1. 看是否在多线程环境下访问。

    是:Vector

    否:转到2

  2. 看增删多还是查询多?

    增删多:LinkedList

    查询多:ArrayList

    不知道:ArrayList

List list = new xxxx();

Set(interface)

set是一个接口,用于描述一个元素不重复的容器。set里面的重复元素只会出现一次。

首先set是一个容器,既然是容器,那么容器所应该具有的功能它都有。也就说Collection接口中定义的方法,Set里都要有。

通过查阅API,发现Set没有自己独有的方法,Set里所有的方法来自于Collection。

Set的实现类

HashSet (普通set)

HashSet的特点:

  1. 不重复
  2. 无序

注意:如果要往HashSet中添加自定义类型的数据,你需要给自定义的类添加equals方法,HashSet在添加元素的时候,会拿现有元素逐一和要添加的元素比较(用equals比较),如果相等了,就不添加,比较一遍之后没有相等的,把元素加进来。

HashSet的创建
  1. HashSet() //创建一个空的Set,初始容量为16

  2. HashSet(int capacity) //创建一个空的Set,初始容量为指定的容量。

  3. HashSet(Collection c) //创建一set,初始内容是c中的元素(会去重)。

HashSet的添加和删除元素API见Set

HashSet没有获取元素的方法,也没有设置元素的方法。

如何取元素呢?—通过遍历来读取。

思考?

能否使用for循环遍历Set?-----不能!因为没有下标

HashSet的遍历

假定有如下Set:

Set<String> s = new HashSet<>();
s.add("zhangsan");
s.add("lisi");
s.add("wangwu");
s.add("zhaoliu");
  1. 使用for…each遍历

    for(String str : s){
        System.out.println(str);//str就是我们set中每个元素
    }
    
  2. 使用Iterator遍历

    Iterator<String> it = s.iterator();
    while(it.hasNext()){
      String str = it.next();
      System.out.println(str);
    }
    
Set另外一个实现类 LinkedHashSet

LinkedHashSet是一个有序的不重复的容器。

特点如下:

  1. 有序(存放顺序有序)
  2. 不重复

小节

Collection是什么?

答:它是一个接口。用来描述容器应该具有哪些功能。(add,addAll,clear,remove,contains,size,iterator)

List是什么?

答:它是一个接口,这个接口继承了Colletion。用来描述一个有序的容器。有序指的是存放顺序。提供了下标的概念(index),围绕下标提供了一堆方法。(add(index,object),addAll(index,collection), remove(index),indexOf(object), lastIndexOf(object), get(index),set(index,object))

List的实现类有哪些?

ArrayList:底层是数组(内存空间连续),查询快,增删慢。

LinkedList:底层是链表,增删快,查询慢。

Vector:线程安全。

List的遍历方法:

for循环

for each

迭代器

Set是什么?

答:set是一个接口,继承于Collection。用来描述不重复的容器。

Set的实现类有哪些?

HashSet:无序不重复。要求容器里的元素实现了equals方法。

LinkedHashSet:有序不重复。有序指的是存放顺序。也需要元素实现equals放法。

TreeSet:有序不重复。有序指的是内容有序。

TreeSet 是一个Set的实现类

TreeSet是一个不重复的容器,而且内容有序。靠Comparable或者Comparator来实现比较,确定是否重复以及谁大谁小。

TreeSet有2大类创建方式:

  1. 自然排序。 元素本身带有比较方法(本质是元素实现了Comparable接口)
  2. 比较器排序。元素本身不具备比较的能力,比较帮元素比较大小。

TreeSet底层靠的二叉树来实现内容有序。小的元素放在树的左分支上,大的放在右分支上。读取元素时,TreeSet使用中序遍历的方式读取元素。

TreeSet添加元素以及删除元素和HashSet一样。

小节

Collection描述一个容器

​ List:有序容器,可重复

​ ArrayList: 数组

​ LinkedList: 链表

​ Vector:数组

​ Set:不可重复,通常是无序的。

​ HashSet:普通集合

​ LinkedHashSet:存放顺序有序,不可重复

​ TreeSet:内容有序,不可重读

Map(接口)

Map是用来描述一个容器,用来描述一个键值对容器。

Map的特点:键不允许重复。

Map和Colletion是平级的。Map数据键值对接口中的根接口。

  1. 添加元素到Map中

    put(key, value) //往Map中存放元素,如果Map中已经有这个key了,会覆盖。如果Map中没有这个key,会把这个键值对存入map

    putAll(Map map) //把另外一个map中的元素全部添加到当前map中,如果有key已经存在了,会产生覆盖。

  2. 移除元素

    remove(key) //根据key移除对应的键值对。

  3. 修改元素

    put(key, value) //如果Map中已经有这个key了,会覆盖. 如果没有就是添加

  4. 查看Map

    size() //查看里面有多少键值对

    containsKey(key) //查看是否有某个key

    containsValue(value) //查看是否有某个value

    get(key) //获取key对应的值。

    keySet() //获取所有的key

    values() //获取所有的value

    entrySet //获取键值对集合

Map的实现类

HashMap

HashMap是一个普通的Map。

创建HashMap
  1. HashMap() 创建一个空的Map,初始容量是16, 加载因子是0.75
  2. HashMap(int capacity) 创建一个空的Map, 初始容量为指定的容量,加载因子是0.75
  3. HashMap(int capacity, float loadFactor) 创建一个空的Map,初始容量和加载因子由参数指定。
  4. HashMap(Map map) 创建一个包含指定键值对的Map。

HashMap的使用

增删改查 见Map的API

Map的遍历

假定有如下Map:

Map<String, Integer> map = new HashMap<>();
map.put("one", 100);
map.put("two", 88);
map.put("three", 96);
map.put("four", 88);

for each遍历

Set<String> keys = map.keySet();
for(String key : keys) {
	System.out.println(key+ "----" + map.get(key));
}

使用迭代器遍历

Iterator<String> it = keys.iterator();
while(it.hasNext()) {
	String key = it.next();
	int value = map.get(key);
	System.out.println(key + "===" + value);
}

for each遍历键值对

Set<Entry<String, Integer>> entries = map.entrySet();
for(Entry<String, Integer> e : entries) {
	System.out.println(e.getKey()+ "__"+ e.getValue());
}

Entry是专门服务于Map的类。它代表键值对对象,内部含有键和值。如果要取出键和值,使用getKey()以及getValue().

Entry本质上Map中内部类。

迭代器遍历键值对

Iterator<Entry<String,Integer>> it2 = entries.iterator();
while(it2.hasNext()) {
	Entry<String, Integer> e = it2.next();
	System.out.println(e.getKey()+"  "+e.getValue());
}
LinkedHashMap

存放顺序有序的Map。特点:存放顺序有序,键不能重复。

TreeMap

key的内容有序的Map。特点:key的内容有序,键不能重复。

HashTable

它与HashMap非常类似,只不过HashTable是线程安全的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值