
14-15章-集合框架
14章-集合框架一
目标
- 数组和集合
- 集合框架体系
- Set/List
一、数组和集合
//容纳一组同数据类型的数据
int[] aryInt = new int[100]; //int数据
//限制:定义相同数据类型(基本数据类型), 固定数值长度
//优点:存/读取
- 数组存取效率高,使用时要求容量大小固定;适合基本数据类型的存取;
- 集合存取效率上有一定的牺牲,集合容量大小可以根据实际需要改变,提供丰富的存取方法,适合成为对象的“容器”;
二、集合框架体系
(了解)集合框架是一个用来代表和操纵集合的统一架构。
- 集合框架被设计成要满足以下几个目标。
- 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
- 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
- 对一个集合的扩展和适应必须是简单的。
- 为此,整个集合框架就围绕一组标准接口而设计。可以直接使用这些接口的标准实现,诸如: LinkedList, HashSet, 和 TreeSet 等,除此之外你也可以通过这些接口实现自己的集合。
- 所有的集合框架都包含如下内容:
- **接口:**是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象
- **实现(类):**是集合的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。
- **算法:**是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。
- 通过观察以下集合框架的图片可以发现:
Java 集合框架主要包括两种类型的容器:一种是集合(Collection),存储一个元素(duix)集合;另一种是图(Map),存储键/值对映射。
Collection 接口的子类型,List、Set ( 以及Queue),还有它们的具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet 等等。
除了集合,该框架也定义了几个 Map 接口和类:HashMap、LinkedHashMap等。Map 里存储的是键/值对。尽管 Map 不是集合,但是它们完全整合在集合中。
java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包。
三、集合Collection接口
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素是对象。
Collection接口的子接口中,有的子集合允许重复元素,有的不允许;有的子集合还分为有序和无序。
其中, Java SDK不提供直接继承自Collection的类,只提供更为具体的子接口:Set/List
1、Collection集合的共性功能:
//确保此集合包含指定的元素(可选操作)。
//返回true调用的结果改变了集合。(返回false集合不允许复制已经包含指定的元素。)
boolean add(Object a);
boolean addAll(Collection<? extends E> c);//将指定集合中的元素添加到集合中。返回true则操作成功改变了原集合
//从这个集合中移除指定元素的一个实例
boolean remove(Object a);
//将指定集合中的元素移除
boolean removeAll(Collection<?> c) ;
//从这个集合中移除所有的元素
void clear();
//判断是否含有指定元素
boolean contain(Object a);
//如果集合不包含任何元素回true。
boolean isEmpty();
//将指定的对象与此集合进行比较,以进行相等性
boolean equals(Object a);
//迭代遍历:返回此集合中的元素的迭代器,元素的返回没有特定的顺序
Iterator<E> iterator();
//返回此集合中的元素的数目
int size();
boolean retainAll(Collection<?> c)
//返回集合中所有元素的数组。
Object[] toArray();
2、Set接口:无序且不许重复元素
Set 具有与 Collection 完全一样的接口,只是行为上不同。
Set 不保存重复的元素,所以,Set 接口存储一组唯一,无序的对象。
特点:
- 不允许重复元素
- 是个无序的集合
- 允许一个null值
- 对集合的add()、 元素的 equals()和hashcode()方法添加了限制
/**
* 特点:
1. 不允许重复元素
2. 是个无序的集合
3. 允许一个null值
4. 对集合的add()、 元素的 equals()和hashcode()方法添加了限制
* @author wyn
*
*/
public class TestSet01 {
public static void main(String[] args) {
//set接口是 无序且不可以重复元素,其常用的实现类有HashSet
Set set = new HashSet();
//添加元素: 单个添加 批量添加
set.add("第一个元素");
set.add(2);
set.add(new Object());
set.add(false);
set.add("gok");
set.add(null);
set.add(4);
System.out.println("set= "+set );
System.out.println("验证Set集合不能添加重复元素...");
set.add(null);
set.add(2);
set.add("gok");
System.out.println("set="+set);
//批量添加:直接把一个set集合temp中的元素添加到调用addall()的set
Set temp = new HashSet();
temp.add("www");
temp.add("gok");
temp.add("tech");
temp.add(2);
set.addAll(temp);
System.out.println("批量添加后的set="+set);
//set的移除:单个
set.remove("www");
System.out.println("单个移除:"+set);
//多个移除
set.removeAll(temp);
System.out.println("多个移除:"+set);
//size
int size = set.size();
System.out.println("size="+size);
//clear()
//set.clear();
System.out.println("set清空后:"+set);
System.out.println("set集合元素是否为空isEmpty=:"+set.isEmpty());
//contain 是否包含该指定元素
System.out.println(set.contains(4));
//如果只想让set存储 指定的某种数据类型元素时,可以使用泛型 <>实现
//泛型是对集合存放的一种规定. 开发过程中,如果没有特殊要求,可以使用泛型<>定义.
Set<String> set2 =new HashSet<String>();
set2.add("福建国科");
// set2.add(222);
System.out.println(set2);
}
}
思考:Set实现不重复的判断思路
添加一个新元素时,分别调用每个对象的hashcode方法,保存成功添加的hashcode值,以便快速查找对应元素。
当出现一个新元素与set中已有元素的hashcode值相同,调用新元素的equals方法进行逻辑判断,如果返回true,则认为重复,添加失败;反之,则添加成功。
——set添加新元素,会判断该hashcode是否和已有的元素一样,一样则继续判断equals方法,如果还是一样则认为重复添加,不一样则添加
/**
* 探究 Set中元素不重复的思想:
* 1.先对象中的hashcode是否一致;
* 2.元素对象hashcode值相等,再判断对象的equals()是否一样,若还是一样则 无法添加到 set集合中
* @author wyn
*
*/
public class Student {
String name;
int id;
public Student(String name, int id) {
super();
this.name = name;
this.id = id;
}
@Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(obj instanceof Student) {
Student s = (Student) obj;
if(name == null ||s.name == null) {
return false ;
}else if(name != s.name) {
return false;
}
}else
return false;
return true;
}
@Override
public int hashCode() {
return 10;
}
public static void main(String[] args) {
Student s1 = new Student("张三", 11);
Student s2 = new Student("张三22", 22);
System.out.println(s1 == s2);//false 判断对象的物理地址,
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s1.equals(s2));
//hashcode值一致,看看set是否可以添加
Set<Student> set = new HashSet<Student>();
set.add(s1);
set.add(s2);
System.out.println("set="+set);
}
}
Set接口的实现类
HashSet | 该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。 由于HashSet中对象不重复,因此要重写对象的equals();且在添加对象时,要先一个个比较是否重复,效率比较低。 |
---|---|
LinkedHashSet | 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。 1. 底层机制链表方式实现; 2.元素有序的; 3.由于用链表实现,因此增删改比较容易,但是查找不易 |
TreeSet | 该类实现了Set接口,可以实现排序等功能。 |
3、List接口:有序可重复元素
List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。
List 接口存储一组不唯一,有序(插入顺序)的对象。
特点:
1. 允许重复元素
2. 具有顺序的集合
3. List中元素通过其整型下标访问
List方法分类
定位方法:get()、set()、add()、remove()、addAll()
搜索方法:indexOf() 、 lastIndexOf()
ListIterator方法:listIterator() 和 subList()
实现类
ArrayList | 该类实现了List的接口。特点:1)底层数组方式实现;2)元素是有序的;3)不是线程同步的;4)由于用数组实现,查找比较快,增删改效率低 |
---|---|
LinkedList | 该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。 例如: List list=Collections.synchronizedList(newLinkedList(...)); LinkedList 查找效率低。 |
Vector | (了解)实现可变长度的对象数组,组件可以使用整型下标访问,线程安全 |
/**
* 特点:
1. 允许重复元素
2. 具有顺序的集合
3. List中元素通过其整型下标访问
4.常用的实现类:ArrayList(数组方式实现 适合查找)\ LinkedList(链表方式实现,更适合做增删改操作)
* @author wyn
*
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class TestList03 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
@SuppressWarnings("rawtypes")
List list2 = new LinkedList();
//单个添加 add
list.add("www");
list.add("gok");
list.add("gok");
System.out.println("单个添加list.add() :"+list);
//批量添加
List<String> tmpList = new ArrayList<String>();
tmpList.add("cn");
tmpList.add(null);
tmpList.add(null);
tmpList.add("福建国科");
list.addAll(tmpList);
System.out.println("批量添加list.addAll() :"+list);
System.out.println("获取list元素个数list.size():"+list.size());
//list.clear();
System.out.println("list :"+list);
System.out.println("清空list元素,list.clear() 并判断list元素是否已空isEmpty=:"+list.isEmpty());
//获取list中指定下标索引的元素内容
System.out.println("获取索引位置为5的元素内容list.get(3):"+list.get(3));
//如果要查询遍历list中的所有元素: for循环/增强for
// for(String str : list) {
// System.out.println("增强for遍历list元素:"+str);
// }
//移除:
// 移除指定位置的元素
// System.out.println("移除指定位置3的元素:"+list.remove(3));
// System.out.println("移除指定位置3的元素后list :"+list);
// 移除指定元素
// System.out.println("移除是否成功:"+list.remove("gok"));
// System.out.println("移除是否成功:"+list.remove("gok"));
// System.out.println("移除是否成功:"+list.remove("gok"));
// System.out.println("移除指定元素 gok ,list :"+list);
System.out.println("-----list的subList方法-------");
System.out.println("原来的list:"+list);
List<String> temp =list.subList(0, 3);
System.out.println("截取的范围temp:"+temp);
System.out.println("截取后的list:"+list);
System.out.println("---如果把截取的范围中的内容清空了------");
temp.clear();
System.out.println("截取的范围temp:"+temp);
System.out.println("截取后的list:"+list);
System.out.println("-----单向迭代器Iterator------");
// //迭代器 :是一个接口,所以只能由其他类来实现; 集合中set/list都有相关的迭代方法
// Iterator<String> it = list.iterator();
// while(it.hasNext()) {
// System.out.println("单向迭代器输出:"+ it.next());
// }
System.out.println("-----双向迭代器ListIterator------");
ListIterator<String> listIt = list.listIterator();
while(listIt.hasNext()) {
System.out.println("从前往后输出:"+ listIt.next());
}
while(listIt.hasPrevious()) {
System.out.println("---从后往前输出:"+ listIt.previous());
}
}
}
4、如何使用迭代器Iterator
例如,显示集合中的每个元素。
一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或ListIterator接口。
迭代器,使你能够通过循环来得到或删除集合的元素。ListIterator 继承了Iterator,以允许双向遍历列表和修改元素。
//包含的方法
boolean hasNext(); //如果仍有元素可以迭代,则true。
Object next(); //返回迭代的下一个元素
boolean remove(); //从迭代器指向的集合中移除迭代器返回的最后一个元素。每次调用next()只能使用一次移除操作。
//迭代器:依次遍历出 集合中的每个元素:
Iterator it = set.iterator();
while(it.hasNext()) { //判断迭代器是否有下一个元素
System.out.println("输出迭代器指向的元素内容:"+it.next()); //输出迭代器指向的下一个元素内容
}
ListIterator<String> listIt = list.listIterator();
while(listIt.hasNext()) {
System.out.println("从前往后输出:"+ listIt.next());
}
while(listIt.hasPrevious()) {
System.out.println("---从后往前输出:"+ listIt.previous());
}
5、Set和List的区别
- Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
- Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
- List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。
四、(了解)老的集合类vector
/**
* vector 老集合中的一种实现类
* 栈Stack,是一种特殊的数据结构. 是先进后出的对象堆栈
* push() 压入栈顶
* pop() 查看栈顶元素并弹栈
* peek() 查看栈顶元素
* @author wyn
*
*/
public class TestStack {
public static void main(String[] args) {
Stack<String> stack = new Stack<String>();
stack.push("www");
stack.push("gok");
stack.push("tech");
stack.push("cn");
stack.push("cn");
stack.push("cn");
System.out.println("查看stack="+stack);
//如何弹出栈中每个元素
// for(int i=0; i<stack.size();i++) { // System.out.println("stack顶:"+stack.pop()); // System.out.println("stack.size()="+stack.size() + ", i="+i); // } while(!stack.isEmpty()) { System.out.println("弹出stack中的每个元素:"+stack.pop()); } System.out.println("查看stack="+stack); } }
15章-框架二
一、图Map接口
Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
特点:
- 关键字唯一。
- 将键映射至值的对象;
- 一个映射不能包含重复键
- 每个键最多都只能映射至一个值。
- 也是无序的
语法:Map< K, V > 标识符;
Map接口和collection接口的不同
- Map是双列的,Collection是单列的
- Map的键唯一,Collection的子体系set是唯一的
- map集合的数据结构值针对键有效,跟值无效。而Collection数据结构是针对元素有效
map实现类
HashMap | HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。 该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,非线程安全的(不支持数据同步)。 |
---|---|
HashTable | 线程安全的(数据同步),效率不如HashMap |
TreeMap | TreeMap继承了AbstractMap,并且使用一颗树。 |
Map集合功能概述:
//添加元素
V put(K key, v value);
//如果键是第一次存储,就直接存储元素,返回null
//如果键不是第一次存储,就用值直接把原来的值替换掉,返回以前的值
//批量添加
void putAll(Map<k,v> m);
//移除所有键值对元素
void clear();
//根据键删除键值对元素。并返回值
v remove(Object key);
//判断是否包含K
boolean containsKey();
boolean containsVaule()
boolean isEmpty()
//根据键获取值
V get(Object key);
//返回映射关系的set试图
Set<Map.Entry<K,V>> entrySet();
//获取集合中所有键的集合
Set<K> keySet();
//获取集合中所有值的集合
Collection<V> values();
//返回map长度
int size();
集合视图
keySet() values() entrySet()
案例实现:统计一个字符串中每个字符出现的次数
package day14_collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* map接口,Map<K,V>键值对.
* 特点:1) 一个键只能对应一个值, 但是值可以对应多个键;
* 2)map也是无序的;
* 3)同时键可以为null; 当键K重复,后面添加的键值 会覆盖之前的键值;
* 常用的方法 put()/putAll() 添加键值; get() 获取键对应的内容; remove();size(); clear()
* @author wyn
*
*/
public class TestMap1 {
public static void main(String[] args) {
Student s1 = new Student("张三", 1001);
Student s2 = new Student("李四", 1002);
Student s3 = new Student("王五", 1003);
Student s4 = new Student("赵六", 1004);
Map<String, Student> map = new HashMap<String, Student>();
map.put("张", s1);
map.put("李", s2);
map.put("王", s3);
map.put("赵", s4);
System.out.println("查看map:"+map);
Student ss1 =map.get("张");
System.out.println(ss1.name);
Student s5 = new Student("张三2", 1021);
Student s6 = new Student("李四2", 1022);
Map<String, Student> temp = new HashMap<String, Student>();
temp.put("张",s5);
temp.put("李2", s2);
map.putAll(temp);
System.out.println("查看map:"+map);
System.out.println(map.size());
map.remove("张");
System.out.println("查看map:"+map);
//map.clear();
System.out.println("判断map是否为空isEmpty=:"+map.isEmpty());
//containsKey
System.out.println("判断是否包含key赵:"+map.containsKey("赵"));
//containsVaule
System.out.println("判断是否包括value=s6 对象:"+map.containsValue(s6)); //false
System.out.println("------map集合视图方法-----");
//Map集合没有iterator,不能直接迭代
//keySet() :获取 map中的所有键
System.out.println("----map中keySet() 获所有键----");
Set<String> keyset =map.keySet();
Iterator it = keyset.iterator(); //获取迭代器
while(it.hasNext()) {
String key =it.next(); //遍历map中所有的key
Integer value = map.get(key);
System.out.println(key+" = "+value); //遍历==>根据键获取值:
}
//values() :获取 map中的所有值
System.out.println("----map中values() 获所有值----");
Collection<Student> values = map.values();
for (Student value : values) {
System.out.println("---map中的value:"+value);
}
//entrySet() :获取 map中每对 键值
System.out.println("----map中entrySet() 获取键值对----");
//Map.Entry说明Entry是map内部接口,将键和值封装在Entry对象中,存储在set集合
Set<Entry<String, Student>> keyvalue =map.entrySet();
for (Entry<String, Student> entry : keyvalue) {
System.out.println("map中键:"+entry.getKey()+"-->值:"+entry.getValue());
}
}
}
二、啥时候使用什么集合?
根据需求选择:
是否需要键值对形式: 是 map 否collection
map :
- 排序 TreeMap 不 HashMap/HashTable
collection:
- 元素唯一: Set :
- 排序 TreeSet 不 HashSet(推荐)
- 元素不唯一 list
- 线程安全: 老集合 Vector
- 不 : Arraylist LindedList
- 增删 LindedList
- 查询 Arraylist
集合框架常用接口特点
Set | 无序,不重复。 | 实现类:hashSet 和treeSet |
---|---|---|
List | 有序 可以重复 | 实现类:ArratList 以及LindedList |
Map | 一对一对的保存的 | 实现类:HashMap 和 HashTable |
三、SortedSet接口
属于set接口, 其实现类是TreeSet。 而TreeSet的底层实现是TreeMap类。
——无序的,不允许重复
- 插入SortedSet 的所有元素都必须实现 内部比较器 Comparable 接口(或者在创建SortedSet时的提供外部比较器Comparator接口 )。
- TreeSet是SortedSet的实现类。
内部比较器接口Comparable
此接口强行实现它的每个类的对象,进行整体排序,这种排序称:类的自然排序,类的compareTo() 被称为 它的自然比较方法。
—— compareTo() 定义在需要比较的类内部;
//比较次对象与指定对象的顺序,如果该对象 < 或= 或> 指定对象 分别返回 -1 1 0
public int compareTo(object a);
Comparator外部比较器
此接口强行 对某个对象 collection 进行整体排序的比较函数,为集合中每个元素 制定排序规则。
——定义在类外部,创建类并实现Comparator接口重写其中的compare(String o1, String o2);
//比较用来排序的两个参数,判断 a<b a=b a>b 分别返回 -1 0 1
public int compare(Object a, Object b);
//创建外部比较器
TestStringComparator3 tCompareto = new TestStringComparator3();
SortedSet<String> sortedSet2 = new TreeSet<String>(tCompareto);//添加外部比较器到实现TreeSet类中构造器
package day14_collection;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* SortedSet是属于set接口的, 所以也是无序的,
* 它的实现类是TreeSet.
* 插入sortedSet的所有元素必须实现内部比较器 或者创建sortedSet类时,提供外部接口.
* 内部比较器 Comparable接口 以及 外部比较器Comparator接口,它们作用主要是 排序:
* 1)内部比较器 主要是针对类,进行排序,称为 自然排序;
* ---在类内部定义 compareTo()
* 2)外部比较器 主要是collection排序,为集合中每个元素 制定排序规则。
* ---定义在类外部,创建类并实现Comparator接口重写其中的compare(String o1, String o2)
* @author wyn
*
*/
public class TestSortedSet2 {
public static void main(String[] args) {
Student s1 = new Student("张三", 1001);
Student s2 = new Student("李四", 1002);
Student s3 = new Student("王五", 1003);
Student s4 = new Student("赵六", 1004);
SortedSet<Object> sortedSet = new TreeSet<Object>();
sortedSet.add("a");
sortedSet.add("e");
sortedSet.add("gg");
// sortedSet.add(new Object()); //object类中没有compareTo方法,报java.lang.ClassCastException
sortedSet.add("c");
sortedSet.add("f");
sortedSet.add("d");
//string类中已经实现了 compareTo方法
System.out.println("查看sortedSet:"+sortedSet);
//创建外部比较器
TestStringComparator3 tCompareto = new TestStringComparator3();
SortedSet<String> sortedSet2 = new TreeSet<String>(tCompareto);
//必须通过构造函数设置外部比较器
sortedSet2.add("a");
sortedSet2.add("e");
sortedSet2.add("gg");
sortedSet2.add("c");
sortedSet2.add("f");
sortedSet2.add("d");
System.out.println("查看sortedSet2:"+sortedSet2);
}
}
/**
* 利用外部比较器,实现sortedSet中插入String 对象,进行 从大到小 排序
* @author wyn
*
*/
class TestStringComparator3 implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return -o1.compareTo(o2);
}
}
总结:
- 当外部比较器Comparator 与 内部比较器 compareble 同时存在:
- 集合优先调用外部比较器Comparator进行排序
- 如果两种比较器都不存在,则无法添加到SortedSet排序接口中,报 类型转换异常。
四、集合和数组工具类
- Collections 是Collection接口的辅助工具类,提供静态的方法操作集合
- Arrays 是数组的帮助类,提供很多静态的方法操作数组
- 相关方法请查看API文档
public class Test03_StringComparator implements Comparator<String> {
public int compare(String o1, String o2) {
// 字符串的降序排列
return -o1.compareTo(o2);
}
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("c");
list.add("b");
list.add("d");
list.add("aa");
System.out.println(list);
//对list中的元素进行排序 升序
//根据元素的自然顺序 对指定列表按升序进行排序。
Collections.sort(list);
System.out.println("排序后 "+list);// [a, aa, b, c, d]
//倒序
//Collections.reverse(list);
//System.out.println("降序后 "+list);
//让集合中的元素降序排列 指定外部比较器(字符串的倒序排列)
Collections.sort(list,new Test03_StringComparator() );
System.out.println("降序后 "+list);
//数组的帮助类Arrays
int[] arr = new int[]{1,7,2,3,6,4,5};
////查看数组
System.out.println(Arrays.toString(arr));
//快速对数组进行排序
Arrays.sort(arr);
//查看数组
System.out.println(Arrays.toString(arr));
五、JDK5新特性
- 静态导入
- 可变参数
- 枚举类型 enum
- forEach 增强的循环迭代方式
- 基本数据类型与封装类自动打包拆包
六、JDK7新特性
- 二进制字面量
- 数字字面量可以出现下划线
- switch语句块可以用字符串
- <>泛型简化
- 异常的多个catch合并,每个异常用 或|
- try- with-resources 语句
七、JDK8新特性
接口中可以定义又方法体的方法:
- 静态修饰方法
- 使用default修饰方法