java的集合类,,存放的是对象的引用,而非对象的本身。
集合类型主要有3种:set(集)、list(列表)、map(映射)
集合
集合框架特点:
- 高性能,基本集合(数组、链表、哈希表、树)的实现是高效的
- 允许不同的类型的集合以相似的方式工作
- 对一个集合的扩展是简单的
因此,整个框架围绕一组标准接口设计。
java集合框架主要包括两种类型的容器:
- Collection(集合)–存储元素集合,包含了集合的基本操作和属性
- Map(图)–存储键值对(Map不是集合,但是整合在集合框架中)
集合框架都包括: - 接口:Collection(其子类有Set、List、Queue)、Map;定义多个接口是为了以不同的方式操作集合对象
- 实现类:集合接口的具体实现,如ArrayList、LinkedList、HashSet、HashTable,它们是可重复使用的数据结构
- 算法:(Collections)即实现类的方法里的一些计算。如排序和搜索,这些算法被称为多态–相同的算法在相似的接口上有着不同的实现
Set、List、Map
- Set:存储一组元素唯一、无序的元素;但是其实现类SortedSet是有序的(只能根据元素本身来访问因此不允许重复)
- List:存储一组元素不唯一、有序(插入顺序)的对象(可通过索引因此可以重复)
- Map:Map.Entry–描述在一个Map的一个元素(键值对),Map的内部类;SortedMap,继承于SortedMap,使Key保持在升序排列。(访问时只能听过key访问value,value可重复)
区别Set和List
- Set接口实例存储的是无序、不重复的数据;List接口实例存储的是有序、重复的元素
- Set检索效率低、插入和删除效率高且插入和删除不会引起元素位置改变(HashSet\TreeSet);List和Set相反且根据实际存储的数据的长度自动增长List的长度(ArrayList\LinkedList*Vector*)
实现List的集合
实现List的集合有ArrayList(最常用、动态数组)、LinkedList(双向链表)、Vector(类似于ArrayList)、Stack
- ArrayList:动态数组,最常用的集合。允许null插入集合。每一个ArrayList都有一个初始容量(10)-代表数组的大小。随着元素的增加,容器的容量也增加。
- LinkedList:双向链表。除了ArrayList的基本操作外额外提供了get、remove、insert方法在LinkedList的首部或者尾部。不支持随机访问。与ArrayList一样,非同步的。
- Vector:同ArrayList类似,但是Vector是同步的。
- Stack:继承Vector,实现一个先进后出的堆栈。提供5个额外的方法使得Vector得以被当做堆栈使用。pop()、push()、peek()、empty()、search()。
实现Set的集合
Set集合允许null存在,但是仅存在一个。实现Set的集合常见的有散列集HashSet、数集TreeSet、链式散列集LinkedHashList。虽然Set中的元素没有顺序,但是元素在Set中的位置有元素的HashCode决定的,其具体位置是固定的(因为底层基于Hash算法实现,和无序不矛盾)。Set集合的去重是由hashcode和equals方法决定的。
- HashSet:由HashMap实现,不保证元素的顺序(元素插入的顺序和输出的顺序不一致)。
- TreeSet:有序,底层基于TreeMap。非线程安全。有两种排序方式–自然排序和定制排序。TreeSet集合不是通过hashcode()和equals()比较元素,而是通过compare()或者compareTo()比较元素是否相等。compare()判断两个函数的ID,相同ID的为重复元素,不会假如集合中。
实现Map的集合
关键词:存储键值对、和Collection无关、key不同但value可以相同。
- HashMap:由哈希表实现,查找对象时通过hashcode()计算其位置–为快速查询设计。内部定义了一个hash表数组。基于拉链法实现的散列表,一般用于单线程程序
- TreeMap:有序的key-value集合。TreeMap判断两个元素相等的标注–两个key通过compareTo()方法,返回0则两个key相等。**若使用自定义的类作为TreeMap的key值,可重写equals()方法,TreeMap中判断相等的标准是–两个key通过equals()返回true,并且通过compareTo()比较返回0.**底层用红黑树实现。一般用于单线程中。
集合算法
集合框架定义了几种算法(为静态方法),可用于集合和映射。
迭代器
所有的集合类均实现了Iterable接口而不是Iterator接口。
Iterable与Iteraor的关系:
JavaSE5引入了新接口Iterable,该接口包含了一个能够产生Iterator的iterator()方法。并且Iterable对象被foreach用来在序列中移动。
Iterable是Collection的顶层接口,所以Iterable是数据结构,用来存放数据的地方。
Iterator定义了迭代逻辑。即用于遍历Collection集合类中数据的标准访问方法。
Iterator与ListIterator解析
Iterator是一个接口,集合的迭代器。集合通过Iterator遍历集合中的元素。提供的API接口:hasNext(),next(),remove()。
ListIterator更加强大,继承于Iterator,但是只能访问各种List类型的集合。
区别:
- ListIterator可以双向移动,但是Iterator只能单向移动;
- ListIterator可以修改和遍历,而Iterator只能遍历。
通常情况下,会遍历一个集合中的元素。一般遍历数组采用for循环或者增强的for(两者可以用于集合框架),另一种是采用迭代器(是一个对象,实现了Iterator接口或者ListIterator接口)遍历集合框架。
注意:Map没有迭代器,若想使用迭代器,则需要先将Map转化为Collection或者其子类对象
- ListIterator继承了Iterator,允许双向遍历列表和修改元素
- 使用迭代器得到或者删除集合的元素
迭代器用法用实例说明
遍历ArrayList
package binaryheap.test;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
public class BH{
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
list.add("TxL");
list.add("!");
//1、把链表变为数组
String[] strAry = new String[list.size()];
list.toArray(strAry);
for (int i = 0; i < strAry.length; i++) {
System.out.println(strAry[i]);
}
System.out.println("-----------------");
//2、采用加强for循环
for (String string : strAry) {
System.out.println(string);
}
System.out.println("-----------------");
//3、迭代器Iterator
Iterator<String> iter = list.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
}
}
结果
hello
TxL
!
-----------------
hello
TxL
!
-----------------
hello
TxL
!
三种方法均用来遍历ArrayList集合,第三种方法采用迭代器。
遍历Map:
package binaryheap.test;
import java.util.*;
import java.util.Map.Entry;
import javax.print.attribute.HashAttributeSet;
public class BH{
public static void main(String[] args) {
//keySet()获取所有的key值
//values()获取所有的value值
//entrySet()获取所有的键值对
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "TxL");
map.put(2, "Hello");
map.put(3, "!");
//1 通过Map.keySet() keySet遍历key和value.keySet是key的集合,Set里是key
for (Integer s : map.keySet()) {
System.out.println("key= " + s + " ,value= " + map.get(s));
}
System.out.println("----------------------------");
//2 entry.set是key——value的集合,Set里是键值对
Iterator<Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry<Integer, String> mEntry = itr.next();
System.out.println("key= "+ mEntry.getKey() + ",value= " + mEntry.getValue());
}
System.out.println("----------------------------");
//3
for (Map.Entry<Integer, String> enty : map.entrySet()) {
System.out.println("key= " + enty.getKey() + " ,value= " + enty.getValue());
}
System.out.println("----------------------------");
//和1相似,通过Map.values()
for (String str : map.values()) {
System.out.println("key= ,,," + " ,value= " + str);
}
}
}
总结
- 集合框架爱提供了预先包装的数据结构和算法来操纵它们。
- 集合是一个对象,可以容纳其他对象的引用
- 集合框架的类和接口均在java.util包中
- 任何对象加入集合类后,自动变为Object类,取出时需要进行强制类型转换
–> JAVA SE (13)