JAVA集合框架总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA集合框架总结相关的知识,希望对你有一定的参考价值。
Java集合框架实现了线性表、链表和哈希表这几类数据结构,为我们在程序开发带来了许多便捷。Java集合框架分为两部分:1.集合,用于存数一个元素集合;2.图,用来存储键值对。该文主要对JDK中Collection和Map两个接口中进行简述。
一、Collection接口
Java集合框架中主要支持三种类型的集合:1.Set(规则集) 2.List(线性表) 3.Queue(队列),其层级关系如图:
Iterator接口
1、规则集Set
HashSet
HashSet扩展于Set接口,可以用来储存互不相同的元素。当程序向HashSet的实例中添加多个相同的元素时,只有一个元素会被存储,因为规则集中只能存储不同的元素。此外,HashSet实例中存储的元素没有特定的顺序,并不会按照插入顺序进行排序。
主要构造方法:
1 +HashSet() //无参构造,创建一个HashSet实例 2 +HashSet(Collection<? extends E> c) //从集合c中创建HashSet实例 3 +HashSet(int size) //创建容量为size的HashSet实例
LinkedHashSet
LinkedHashSet用一个链表实现来扩展HashSet类,因此依旧无法添加重复的元素。在HashSet中,我们无法对其实例的元素进行排序,而当我们需要对元素插入的顺序进行排序时,LinkedHashSet是一个可用的选择。
主要构造方法:
1 +LinkedHashSet() //创建一个无参实例 2 +LinkedHashSet(Collection<? extends E> c) //从集合c中创建LinkedHashSet实例 3 +LinkedHashset(int size) //创建一个容量为size的实例
TreeSet
以下为实现比较器顺序的一个案例(以学生信息为例,可通过学号排序,也可通过成绩排序):
1 import java.io.Serializable; 2 import java.util.Comparator; 3 4 public class StudentComparator implements Comparator<Student>, Serializable{ //Java所有集合中都实现了序列化,为了能成功排序,必须实现该接口 5 6 @Override 7 public int compare(Student o1, Student o2) { 8 if (o1.getGrade() > o2.getGrade()) 9 return 1; 10 else if (o1.getGrade() == o2.getGrade()) 11 return 0; 12 else 13 return -1; 14 } 15 16 } 17 [java] view plain copy 18 19 <pre name="code" class="java">import java.util.Iterator; 20 import java.util.TreeSet; 21 22 public class TestTreeSet { 23 public static void main(String[] args) { 24 TreeSet<Student> set = new TreeSet<>(new StudentComparator()); 25 set.add(new Student(1, 80)); 26 set.add(new Student(2, 50)); 27 set.add(new Student(3, 78)); 28 29 Iterator<Student> iterator = set.iterator(); //使用迭代器遍历元素 30 while (iterator.hasNext()) { 31 Student student = (Student) iterator.next(); 32 System.out.println(student.getId() + " " + student.getGrade()); 33 } 34 } 35 } 36 37 /*以下为输出结果 38 2 50 39 3 78 40 1 80*/
2、线性表List
在程序开发中,往往我们需要向集合中添加相同的元素,线性表实现了添加重复元素的功能,此外,线性表也允许通过下标访问集合中指定位置的元素。线性表是一个有序允许重复的集合。
List接口中方法有:
1 +add(int index) //指定下标添加元素 2 +addAll(int index, Collection<? extends E> c) //指定下标处添加c中所有元素 3 +get(int index) //返回指定下标元素 4 +lastIndexOf(Object o) //返回相同元素的下标 5 +listIterator() //返回遍历列表的迭代器 6 +listIterator(int startIndex) //返回从startIndex开始的所有元素的迭代器 7 +remove(int index) //删除指定下标的元素 8 +set(int index, E element) //设置指定下标的元素 9 +subList(int fromIndex, int toIndex) //返回从fromIndex到toIndex元素子列表
ArrayList
ArrayList使用数组来存储元素,这个数组是动态创建的,当插入的元素超过数组的长度时,就会创建更大的数组,并把当前数组的元素复制到新的数组当中。因此相对于数组来说ArrayList更具有灵活性。
构造方法:
1 +ArrayList() //创建一个空列表 2 +ArrayList(Collection<? extends E> c) //从集合c中创建实例 3 +ArrayList(int size) //创建一个大小为size的空列表
此外,ArrayList中有trimToSize()方法可以将ArrayList的容量缩小到当前列表大小。
在Java2之前引入了向量类Vector,其使用方式与ArrayList类似,但Vector实现了现成同步,以避免多线程访问数据时引起数组损坏。
LinkedList
LinkedList
PriorityQueue
此类实现了优先队列,在默认情况下,该队列的初始容量为11。其实例所存储的元素默认以自然顺序排列,因此自然顺序下最小的元素会优先出队。队列中可能出现对个优先级相同的元素,那么拥有相同优先级的元素会有其中任意一个优先出队。在讲述TreeSet时提到过使用Comparator接口来实现比较器顺序,在优先队列中依然可行。
构造方法:
1 +PriorityQueue() //创建一个默认的优先队列 2 +PriorityQueue(int size) //创建一个容量为size的优先队列 3 +PriorityQueue(Collection<? extends E> c) //从集合c中创建优先队列 4 +PriorityQueue(int size, Comparator<? super E>) //创建一个容量为size且拥有比较器顺序的优先队列
二、Map接口
Map接口中有如下方法:
1 +clear(); //删除图中所有条目 2 +containsKey(Object key) //图中如果包含指定键值返回true 3 +containsValue(Object value) //图中如果包含指定值返回true 4 +get(Object key) //获得指定键值对应的值 5 +entrySet() //返回包含图中条目的规则集 6 +isEmpty() //判断是否空 7 +keySet() //返回图中包含键值的一个规则集 8 +put(Object key, Object value) //添加键值对 9 +putAll( ) //将指定实例中的键值对添加到当前实例中 10 +remove(Object key) //删除指定键值对应的值 11 +size() //键值对个数 12 +values() //返回图中包含的集合
HashMap
与HashSet相类似,HashMap实例存储的键值对是无序的,不会根据插入的顺序将键值对进行排序,并且存储顺序是随机的。
LinkedHashMap
该类扩展自HashMap,实现了插入的键值对的排序。其排序方式有两种,一种根据插入顺序排序(插入顺序),一种根据最后一次被访问的顺序排序(访问顺序)。
通过以下构造方法说明:
1 +LinkedHashMap(int size, float loadFactor, boolean Order)
//创建一个容量为size的图,客座率为loadFactor(即存储的键值对超过该值,会自动增加图的容量,一般为0.75f),true代表访问顺序,false代表插入顺序
TreeMap
与TreeSet类似,可通过两种方式来实现对图中的键值进行排序。
上述三种具体类都可以通过构造方法从其他图中进行创建。
1 import java.util.HashMap; 2 import java.util.LinkedHashMap; 3 import java.util.Map; 4 import java.util.TreeMap; 5 6 public class TestMap { 7 public static void main(String[] args) { 8 Map<String, Integer> hashmap = new HashMap<>(); 9 hashmap.put("s1", 10); 10 hashmap.put("s2", 6); 11 hashmap.put("s3", 7); 12 System.out.println("HashMap:"); 13 System.out.println(hashmap); 14 15 Map<String, Integer> linkedHashMap = new LinkedHashMap<>(3, 0.75f, true); 16 linkedHashMap.put("s1", 10); 17 linkedHashMap.put("s2", 6); 18 linkedHashMap.put("s3", 7); 19 System.out.println("LinkedHashMap:"); 20 System.out.println(linkedHashMap); 21 22 Map<String, Integer> treeMap = new TreeMap<>(); 23 treeMap.put("s1", 10); 24 treeMap.put("s2", 6); 25 treeMap.put("s3", 7); 26 System.out.println("TreeMap:"); 27 System.out.println(treeMap); 28 } 29 30 } 31 /*输出结果 32 HashMap: 33 {s3=7, s1=10, s2=6} 34 LinkedHashMap: 35 {s1=10, s2=6, s3=7} 36 TreeMap: 37 {s1=10, s2=6, s3=7}*/ 38
总结
HashSet与HashMap都不能存储相同的元素。其判断是否存在相同元素通过hashcode()和equals()两个方法来实现,当插入一个新元素或键值时,会先判断集合或图中是否存在hashcode()值相同的元素,伪代码如下:
1 if (两个元素hashcode值相等) { 2 if (两个元素相等) 3 return true; //不添加 4 else 5 return false; //添加 6 }
由此可知,hashcode相等的两个元素未必相同,但两个相同的元素hashcode必定相同。
在Set接口的实例中如果不需要维护元素插入的顺序,则使用HashSet,因为HashSet更高效率。Map接口中的HashMap也是如此。
在List接口中,ArrayList在尾部提取和插入元素比较高效,LinkedList在任意位置删除和插入元素较高效。
如果在应用程序中不需要添加重复的元素,那么规则集会是最高效的集合。
以上是关于JAVA集合框架总结的主要内容,如果未能解决你的问题,请参考以下文章