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体系
Set接口
~Set接口保存无序的、不可重复的元素。
~HashSet的元素可为null,线程不安全。
~LinkedHashSet的元素有序(插入顺序)。
~TreeSet的元素有序(比较顺序)。
Queue接口
~Deque是双端队列。
~PriorityQueue可按大小排序。(插入还是比较?)
~ArrayDeque是队列,先进先出。
List接口
~List接口保存有序的、可重复的元素。
~Vector与Stack线程安全,但性能差。
~ArrayList、LinkedList线程不安全。
~LinkedList是双向链表,可做队列&栈。
Map体系
~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的重点&核心知识,
也是各大公司面试题的考点之一,希望大家可以掌握。