java集合框架

Java集合学习笔记

学习一个知识点我觉得有三点必须要弄明白,what(是什么)、why(为什么)how(怎么做),至少要从这三个角度来思考问题,学习都是参考《java核心技术 卷1》这本书,这本书讲的很详细。

 

What:集合到底是什么?

Ans:为了解决程序设计过程中的存储问题,java设计人员开发了一组功能完善的数据结构。

 

How:怎样定义并实现它?

Ans:先定义规范(接口),再具体实现。

 

从开始学习前,必须要对现有的结合中的数据结构有一个宏观的了解,这个图是我从网上copy(感觉这个图有点问题,不过大致意思能够表达出来)下来的,自己画好麻烦。。。


数据结构知识基础回顾

我们学过哪些数据结构?

 

线性表

顺序表示:

链式表示:

线性链表

循环链表

双向链表

操作受限的线性表:

队列

PS:栈和队列都有顺序和链式两种表示方式。

 

 

非线性结构:

树:

重点:二叉树

 

 

 

 

基本接口(最基础的规范)


Collection继承Iterator接口,则实现Collection接口的类都提供遍历的功能,还有addremovesize等基本操作,集合还提供两外一个基本接口Map,但是保存的是/值对

子接口

Collection的两个重要的子接口:List,SetMap接口,以及他们的常用实现类。

接口

实现类

List

ArrayList

LinkedList

Set

HashSet

TreeSet

Map

HashMap

TreeMap

 


List(线性表)

List不是链表,而是一张线性表,里面的元素可以重复,但是要按顺序排列着。

实现:

1)、ArrayList:数组列表,封装了一个动态再分配的对象数组。

2)、LinkedList,这个才是链表,而且是双向链接的,LinkedList.add方法是将对象添加到链表的尾部(因为LinkedList还实现了Deque接口),如果要添加到指定位置需要和迭代器配合使用

LinkedList类的常见使用:

public class A {
	public static void main(String[] args) {
		List<Integer> list = new LinkedList<>();
		list.add(1);
		list.add(2);
		list.add(3);//1-->2-->3,先添加的元素在尾部
		Iterator<Integer> listiterator = list.listIterator();
		//遍历的使用
		while(listiterator.hasNext()){
			listiterator.next();//跳过第一个元素
			if(listiterator.hasNext()){
				listiterator.next();//删除第二个元素
				listiterator.remove();
			}
		}
		System.out.println(list);
	}

}

两个类的区别:当我们要进行大量的删除、修改等操作的时候,要选用LinkedList这个类,对于链表来说,删除等更新操作速度很快,但是

不适宜使用大量查询操作,即使该类提供了get(int index)这个方法,而应该使用ArrayList类。

 

Set接口

Set没有重复元素的无序的集合,add方法执行成功的前提条件是set中尚未存在该元素,更确切地讲,set不包含满足e1.equals(e2)的元素对e1e2,并且最多包含一个 null 元素

实现:

1)、HashSet(散列集)

2)、TreeSet(树集)

 

HashSet散列集:

在学习HasSet之前,我们首先要搞明白一个概念,到底什么是哈希?

以每个对象的属性值为变量,通过一种函数为每个对象计算出一个函数值,把这个值解释为一块连续存储空间的单元地址(哈希码),更确切的说,具有相同数据域的对象将产生不同的散列码。

 

这么做有什么好处呢?为每个对象分配一个哈希码,如果两个对象的数据域都是相同的,但是在不同的物理空间上,我们应该处理呢?

使用散列码的最终目的是为了加快查找的速率,并分散对象,如果两个对象的数据域是相同的,那么就会产生哈希冲突,解决方式有链表法、开放地址法,在java里面采用的是前者。

即使产生冲突,我们查找对象的速度也依然很客观。最开始,我们提到,set是无序的集合,对于元素的访问是随机的,使用哈希可以帮助我们查找。

Ps:如果散列集中存储的对象的类型是我们自己定义的,我们就要重写hashcode方法。

 

 

TreeSet树集:


TreeSet类与散列集十分类似,不过比散列集有所改进,树集是一个有序集合,因为其实现了SortedSet接口。

SortedSet接口:

  Comparator<? super E> comparator();

//返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null

TreeSet的排序过程是如何实现的呢?

采用树结构(红黑树,呵呵,这个我也没学过。。。),每次添加元素到树中的时,都被放置在正确的位置上,这样迭代器就总是以排序好的顺序来访问每个元素,每次添加都要进行比较,所以添加元素的速率就要

相比较HashSet慢。

 

TreeSet中的元素是如何进行比较的呢?

在默认情况下,树集假定插入的元素实现了Comparable接口。

Public interface Comparable<T>{

Int compareTo(T other);

 

}

但是这样的实现真的好吗?让我们看一个具体实现:

Class Item implements Comparable<Item>{

Public int compareTo(Item other){

Return part-other.part;

}

}

Item类实现了这个接口,这一个TreeSet类中,我们按照这个顺序来排列,但是如果我们又定义了一个TreeSet,里面也保存的是Item类型的元素,但是我们不希望使用这个排序方式,这样我们就体现了这种的局限性。在这种情况下,我们可以通过Comparator(注意不是Comparable对象,方法也是不一样的)对象传递给TreeSet构造器来告诉树集应该使用什么样的比较方法。

TreeSet(Comparator<? super E> comparator)

 

Ps:在这里大家要区分ComparableComparator接口。

 

 

Map

映射表用来存放键/值对,如果提供了键,就能找到值,一个映射表中不能包含重复的键,每个键最多只能映射一个值。

Map接口提供三种视图,键集、值集、键值映射集,如下:

Set<K> keySet()

Collection<V> values()

Set<Map.Entry<K,V>> entrySet()

 

为什么要提供三种视图呢?

因为Map接口不是从Collection接口继承而来,没有迭代器,这几种视图都可以提供给我们遍历。

 

实现:

1)、HashMap

2)、TreeMap

 

HashMap,散列映射表,对键进行散列

TreeMap,树映射表,用键的整体顺序来对元素进行排序。


常规用法:

public class A {
	public static void main(String[] args) {
		Map<String, String> map  =  new HashMap<>();
		map.put("1", "a");
		map.put("2", "b");
		map.put("3", "c");
		map.put("4", "d");
		for(Map.Entry<String, String > entry:map.entrySet()){
			String key = entry.getKey();
			String value = entry.getValue();
			System.out.println(key+" "+value);
		}
	}

}

还有不少实体类,我没有一一介绍,只介绍了自己平时用的比较多的,还有几点没有写,Collections的用法、集合与数组之间的转换等,这里就不写了,回头写一篇这些集合类的具体实现。

 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值