9.偏头痛杨的Java入门教学系列之初级集合框架篇

复习

1.使用接口的好处是什么?

2.Java的工作机制?

3.什么是方法重写与方法重载?

4.什么是Java三要素?

5.抽象类与接口的区别?

6.多态的三个必要条件?

7.this与super的用法?

8.final的用法?

9.unchecked异常与checked异常的区别?

10.JDK&JRE&JVM分别是什么以及他们的关系?

 

前文链接

1.偏头痛杨的Java入门教学系列之认识Java篇

http://blog.csdn.net/piantoutongyang/article/details/70138697

2.偏头痛杨的Java入门教学系列之变量&数据类型篇

http://blog.csdn.net/piantoutongyang/article/details/70193622

3.偏头痛杨的Java入门教学系列之表达式&运算符&关键字&标识符&表达式篇

http://blog.csdn.net/piantoutongyang/article/details/71027446

4.偏头痛杨的Java入门教学系列之初级面向对象篇

http://blog.csdn.net/piantoutongyang/article/details/78135129

5.偏头痛杨的Java入门教学系列之流程控制语句篇

http://blog.csdn.net/piantoutongyang/article/details/71698589

6.偏头痛杨的Java入门教学系列之数组篇

http://blog.csdn.net/piantoutongyang/article/details/72510787

7.偏头痛杨的Java入门教学系列之进阶面向对象篇

http://blog.csdn.net/piantoutongyang/article/details/73176373

8.偏头痛杨的Java入门教学系列之异常篇

http://blog.csdn.net/piantoutongyang/article/details/73687445

 


前戏

存储若干对象到集合中,类似于数组的升级版,可以对集合中的对象进行存&取,遍历等等操作。

集合是非常有用的知识点,在后面会用到从数据库中查询数据,返回给我们来使用,

那些数据库中的数据就可以存储在集合之中。

本章只是入门篇,集合里面的水很深,后续依然会有文章提供进阶篇。

 


什么是集合框架

整个集合框架就围绕一组标准接口而设计。你可以直接使用这些接口的标准实现,

诸如: LinkedList, HashSet, 和 TreeSet等,除此之外你也可以通过这些接口实现自己的集合。

 

集合框架是一个用来代表和操纵集合的统一架构。

所有的集合框架都包含如下内容:

接口

代表集合的抽象数据类型,只是定义没有实现,接口允许实现类来为其实现细节。

 

实现(类)

是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构。

 

算法

是实现集合接口的对象里的方法执行的一些有用的计算。

例如:搜索和排序,相同的方法可以在相同的接口上有着不同的实现。

 

除了集合,该框架也定义了几个Map接口和类。Map里存储的是键/值对。

尽管Map不是Collection,但是它们完全整合在集合中。

集合框架的类和接口均在java.util包中。

 


集合框架体系

集合体系又分为两大分支,分别为Map接口分支与Collection接口分支。

Map接口与Collection接口是两个接口,千万不要弄混,

Map接口的应用非常广泛,主要用于存储KV结构数据。

这两张图需要牢记并且能拥有徒手画图的能力

 

虚线:实现接口

实线:继承父类

箭头方向:子类指向父类&实现类指向接口

 

Collection体系

9.偏头痛杨的Java入门教学系列之初级集合框架篇_第1张图片

 

Set接口

~Set接口保存无序的、不可重复的元素。

~HashSet的元素可为null,线程不安全。

~LinkedHashSet的元素有序(插入顺序)。

~TreeSet的元素有序(比较顺序)。

 

Queue接口

~Deque是双端队列。

~PriorityQueue可按大小排序。(插入还是比较?)

~ArrayDeque是队列,先进先出。

 

List接口

~List接口保存有序的、可重复的元素。

~Vector与Stack线程安全,但性能差。

~ArrayList、LinkedList线程不安全。

~LinkedList是双向链表,可做队列&栈。

 

 

Map体系

9.偏头痛杨的Java入门教学系列之初级集合框架篇_第2张图片

~HashMap的元素可为null,无序,线程不安全。

~Hashtable的元素不为null,无序,线程安全。

~LinkedHashMap有序,链表保存内部顺序。(插入顺序)

~IdentityHashMap用==而非equals比较键。

~TreeMap是红黑树的实现,按大小排序。(比较顺序)

~WeakHashMap:实现弱引用的HashMap。

 

Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中, 

所以当使用集合框架的时候需要进行导包。

 


集合接口与实现类

接口名称

接口描述

Collection

Collection是最基本的集合接口,一个 Collection 代表一组 Object,

Java不提供直接继承自Collection的类,

只提供继承于的子接口(如List和set等)。

List

List是Collection的子接口,List保存有序的、可重复的元素。

 

List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。

查找元素效率高,插入删除效率低,因为会引起其他元素位置改变。

 

使用List能够精确的控制每个元素插入的位置,

能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素。

 

实现类有:ArrayList、LinkedList、Vector。

Set

Set是Collection的子接口,Set保存无序的、不可重复的元素。

(判断是否重复要重写equals与hashcode方法,下面会有详细说明)

 

Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。

 

实现类有:EnumSet、HashSet、TreeSet

SortedSet

继承于Set保存有序的集合。

Map

将唯一的键映射到值,用于存储键/值映射关系,键/值=key/value。

例如:

key=5,value=user5对象;

key=6,value=user6对象;

Map.Entry

描述在一个Map中的一个元素(键/值对)。是一个Map的内部类。

SortedMap

继承于Map,使Key保持在升序排列。

Enumeration

这是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。

这个传统接口已被迭代器取代。

 

实现类名称

实现类描述

ArrayList

List接口的实现类,实现了可变大小的数组,随机访问和遍历元素时,

提供更好的性能。

该类也是线程不安全的,避免多线程环境下使用该类。

LinkedList

该类实现了List接口,允许有null(空)元素。

主要用于创建链表数据结构,该类没有同步方法,

如果多个线程同时访问一个List,则必须自己实现访问同步,

解决方法就是在创建List时候构造一个同步的List。

Vector

该类和ArrayList非常相似,但是该类是同步的,可以用在多线程的情况,

该类允许设置默认的增长长度,默认扩容方式为原来的2倍。

Stack

栈是Vector的一个子类,它实现了一个标准的后进先出的栈。

HashSet

该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,

允许包含值为null的元素,但最多只能一个。

LinkedHashSet

具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。

TreeSet

该类实现了Set接口,可以实现排序等功能。

HashMap

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。 

该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,

最多允许一条记录的键为null,不支持线程同步。

Hashtable

Hashtable 是 Dictionary(字典) 类的子类,位于 java.util 包中。

 

 

 


核心集合类用法

List用法

public class ArrayListDemo1 {
	public static void main(String[] args) {
		// 定义并创建一个ArrayList对象,list虽然允许存放不同类型的数据,但通常不建议这么做。
		List list1 = new ArrayList();
		// 判断list是否有元素
		System.out.println(list1.isEmpty());
		// 添加list元素
		list1.add(5);
		for (int i = 0; i < 5; i++) {
			list1.add(i);
		}
		list1.add(2);

		System.out.println(list1);
		// 从list获取下标为x的元素
		System.out.println(list1.get(1));

		// 如果list中有此元素则返回该元素的下标(从0开始),否则返回-1
		System.out.println("index==>" + list1.indexOf(2));
		// 如果list中有此元素则返回最后一次出现的该元素的下标(从0开始),否则返回-1
		System.out.println("index==>" + list1.lastIndexOf(2));

		// list中元素个数
		System.out.println("~~~" + list1.size() + "~~~");

		// 删除list元素,允许按下标删和按元素删两种方式
		list1.remove(new Integer(3));

		// 指定位置添加元素,效率低,因为会把大家都往后移动。。。。
		list1.add(0, 9);
		System.out.println(list1);
		// 指定位置添加元素,直接覆盖
		list1.set(0, 8);
		System.out.println(list1);

		// list转数组
		Integer[] xxx = list1.toArray(new Integer[] {});
		for (Integer a : xxx) {
			System.out.println("array===>" + a);
		}

		// list添加另外一个list
		List list2 = new ArrayList();
		list2.add(10);
		list2.add(11);
		list2.add(12);
		list1.addAll(list2);
		System.out.println(list1);

		// 切分出一个子list,类似于String的substring()
		List subList1 = list1.subList(0, 3);
		System.out.println("subList1=" + subList1);

		// list中是否包含某个元素
		if (list1.contains(2)) {
			System.out.println("2 yes");
		} else {
			System.out.println("2 no");
		}

		// 注意,此处我删掉了list里的一个元素,这个元素原本是属于list2的,然后containsAll就失败了。
		list1.remove(new Integer(5));
		if (list1.containsAll(list2)) {
			System.out.println("list2 yes");
		} else {
			System.out.println("list2 no");
		}

		// 其实在list1中的list2已经不完整了,但是也能把剩余的全部干掉。
		list1.removeAll(list2);
		System.out.println(list1);
		list1.add(1);

		List list3 = new ArrayList();
		list3.add(1);

		// 只保留参数与list1的交集,即1;list是3,2,1,参数是1,则保留1。如果list是1,参数是3,2,1则返回false,没有变化。
		System.out.println(list1.retainAll(list3));
		System.out.println(list1);

		// 清空list
		list1.clear();
		System.out.println(list1);

		// list的四种遍历方式
		List list4 = new ArrayList();
		list4.add("A");
		list4.add("B");
		list4.add("C");

		// 第1种使用foreach遍历List
		for (String str : list4) { //
			System.out.println(str);
		}

		// 第2种使用原始for
		for (int i = 0; i < list4.size(); i++) {
			System.out.println(list4.get(i));
		}

		// 第3种使用迭代器进行相关遍历
		Iterator ite = list4.iterator();
		while (ite.hasNext()) {
			System.out.println(ite.next());
		}

		// 第4种使用JDK8的Lambda
		list4.forEach(item->System.out.println(item));
	}
}

 

LinkedList用法

public class LinkedListDemo1 {
	public static void main(String[] args) {
		// 创建并初始化链表,LinkedList既可以当队列也可以当栈
		LinkedList books = new LinkedList<>();

		// 加入到链表的头部
		books.push("a");
		// 加入到栈的尾部,注意此处不会因为写在前面就放在链表的前面
		books.offer("b");
		// 加入到链表的头部(最后加的放在链表的最上面)
		books.offerFirst("c");
		//加入到链表的尾部
		books.addLast("d");
		//加入到链表的尾部
		books.addLast("e");
		//加入到链表的尾部
		books.addLast("f");
		//从 头删除一个链表元素
		books.removeFirst();
		//从 尾删除一个链表元素
		books.removeLast();
		
		// 遍历链表
		for (int i = 0; i < books.size(); i++) {
			System.out.println(books.get(i));
		}
		// 访问但不删除栈顶的元素
		System.out.println(books.peekFirst());
		// 访问但不删除队列的最后一个元素
		System.out.println(books.peekLast());
		// 将栈顶的元素弹出栈
		System.out.println(books.pop());
		// 访问并删除队列的最后一个元素
		System.out.println(books);
		System.out.println(books.pollLast());
		System.out.println(books);
		
		System.out.println("----------");
		//可以给定一个Collection作为参数来创建链表
		List list = new ArrayList<>();
		list.add("g");
		list.add("h");
		list.add("i");
		LinkedList books2 = new LinkedList<>(list);
		System.out.println(books2);
	}
}

 

Map用法

public class HashMapDemo2 {
	public static void main(String[] args) {
		Map map = new HashMap();
		map.put("1", "value1");
		map.put("2", "value2");
		map.put("3", "value3");

		// 第一种:普遍使用,二次取值
		System.out.println("通过Map.keySet遍历key和value:");
		for (String key : map.keySet()) {
			System.out.println("key= " + key + " and value= " + map.get(key));
		}

		// 第二种
		System.out.println("通过Map.entrySet使用iterator遍历key和value:");
		Iterator> it = map.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry entry = it.next();
			System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
		}

		// 第三种:推荐,尤其是容量大时
		System.out.println("通过Map.entrySet遍历key和value");
		for (Map.Entry entry : map.entrySet()) {
			System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
		}

		// 第四种
		System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
		for (String v : map.values()) {
			System.out.println("value= " + v);
		}

		// 第五种JDK8
		map.forEach((k, v) -> {
			System.out.println(k + " " + v);
		});
	}
}

 


总结

今天我们学习了java的集合,是java的重点&核心知识,

也是各大公司面试题的考点之一,希望大家可以掌握。

你可能感兴趣的:(#,Java教学系列)