Java集合框架简介
集合概念
因为数组的大小是固定的,所以设计了集合来满足数组的不足,集合可以随着数据的增大而增大,空间大小是不固定的
集合框架设计满足几个目标
- 框架必须是高性能的,基本集合的实现必须是高效的
- 对集合的扩展和适应是简单的
Collection集合
Collection接口的一些常用方法
/* * boolean add(E e) //添加一个元素,List中,可以添加重复元素,总是返回true,Set中,添加重复元素,返回false * void clear() //清空集合 * boolean contain(Object o) //是否包含某元素 * boolean isEmpty() //判断集合是否为空 * boolean remove(Object o) //移除某个元素 * int size(Object o) //返回集合元素个数 * */
public class Demo1_Collection {
public static void main(String[] args){
Collection c=new ArrayList();
c.add("Hi"); //添加元素
c.add("HelloWorld");
c.add("Hi");
System.out.println(c); //ArrayList的父类的父类重写了toString方法,返回的不是Object的toString类型
c.remove("Hi"); //移除Hi元素
System.out.println(c);
// c.clear(); //清空集合
// System.out.println(c);
System.out.println(c.contains("Hi"));//是否包含HI
System.out.println(c.size()); //返回元素个数
}
}
迭代器遍历
/* * 集合中迭代器的简单使用 * */
public class Demo2_Collection_Iterator {
public static void main(String[] args) {
Collection c=new ArrayList();
c.add("chengfeilong");
c.add("chenlixiang");
c.add("qinhongzhi");
Iterator it=c.iterator(); //获取迭代器
while (it.hasNext())
System.out.println(it.next());
}
}
List
/* * List接口特有的方法 * void add(int index, E element) * E remove(int index) * E get(int index) * E set(ind index,E element) * */
public class Demo1_List {
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
// list.add(1,"e");//在索引为1的位置,插入"e"元素
// list.add(10,"e"); //java.lang.IndexOutOfBoundsException,插入索引位置时,注意索引的大小
System.out.println(list);
list.remove(1); //移除索引值位置的元素,返回被删除的元素,删除的时候不会自动装箱
System.out.println(list);
// System.out.println(list.get(1)); //获取索引值位置的元素,所以可以用此方法遍历集合
// 遍历集合
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
list.set(1,"e"); //修改索引值位置的元素
System.out.println(list);
}
}
ArrayList
- ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用
ensureCapacity
操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。 - ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
- ArrayList 实现了RandomAccess 接口, RandomAccess 是一个标志接口,表明实现这个这个接口的 List 集合是支持快速随机访问的。在 ArrayList 中,我们即可以通过元素的序号快速获取元素对象,这就是快速随机访问。
- ArrayList 实现了Cloneable 接口,即覆盖了函数 clone(),能被克隆。
- ArrayList 实现java.io.Serializable 接口,这意味着ArrayList支持序列化,能通过序列化去传输。
- 和 Vector 不同,ArrayList 中的操作不是线程安全的!所以,建议在单线程中才使用 ArrayList,而在多线程中可以选择 Vector 或者 CopyOnWriteArrayList。
ArrayList实现去重
/* * ArrayList实现集合重复数据的去除 * 思想:创建一个新的集合 * */
public class Demo3_ArrayList {
public static void main(String[] args) {
ArrayList list=new ArrayList();
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("c");
list.add("d");
ArrayList newList=getSingleList(list);
System.out.println(newList);
}
public static ArrayList getSingleList(ArrayList list) { //传入旧集合,处理掉重复的元素,组成一个新的集合
ArrayList newList = new ArrayList(); //新的集合用来存放旧集合里不重复的元素
Iterator it = list.iterator(); //获取迭代器
while (it.hasNext()) //判断是否为空
{
Object o = it.next(); //取出来元素
if(!newList.contains(o)) //判断新集合是否包含这个元素
newList.add(o); //不包含,就添加到新集合中去
}
return newList; //返回新的集合,此时不包含重复元素
}
}
ArrayList实现三种遍历方式
/* * 三种迭代的比较 * */
public class Demo5_ThreeIterator {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
//三种遍历方式
System.out.println("迭代器遍历");
Iterator<String> it=arrayList.iterator();//获取迭代器
while (it.hasNext())
System.out.print(it.next()+" ");
System.out.println();
System.out.println("for循环遍历");
for (int i = 0; i < arrayList.size(); i++) {
System.out.print(arrayList.get(i)+" ");
}
System.out.println();
System.out.println("foreach循环遍历");
for(String s : arrayList)
System.out.print(s+" ");
}
}
LinkedList
- LinkedList是一个实现了List接口和Deque接口的双端链表
- LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性;LinkedList不是线程安全的,如果想使LinkedList变成线程安全的,可以调用静态类Collections类中的synchronizedList方法:
LinkedList特有方法
/* * LinkedList特有功能 * public void addFirst()和addLast() * public E getFirst()和getLast() * public E removeFirst()和removeLast() * public E get(int index)和ArrayList的不一样 * */
public class Demo4_LinkedList {
public static void main(String[] args) {
LinkedList linkedList=new LinkedList();
linkedList.addFirst("a"); //头部添加一个元素
linkedList.addFirst("b");
linkedList.addFirst("c");
linkedList.addFirst("d");
linkedList.addLast("g"); //尾部添加一个元素
linkedList.removeFirst(); //删除头部元素
linkedList.removeLast(); //删除尾部元素
Object o=linkedList.get(3); //根据索引找到元素
System.out.println(o);
System.out.println(linkedList);
}
}
Vector
- Java1.0版本中已经存在了,早期的集合工具类,后来被并入到Java集合框架中,逐渐被ArrayList替代
- 因为是同步的,所以线程安全,不要求线程安全的情况下,建议使用ArrayList代替
/* * 早期Vector类实现集合功能实例 * */
public class Demo2_Vector {
public static void main(String[] args) {
Vector v=new Vector();
v.addElement("a"); //添加元素
v.addElement("b");
v.addElement("c");
v.addElement("d");
Enumeration en=v.elements(); //获取迭代器
while (en.hasMoreElements()) //判断是否为空
{
System.out.println(en.nextElement()); //输出值
}
}
}
Set
HashSet
HashSet如何保证元素唯一的
- HashCode方法里常量为什么是31?
- 31是个质数
- 31这个质数不大也不小
- 好算,31是2的5次方减1,也就是2左移5位-1
- equals方法健壮性
- 我们使用Set集合都是需要去除掉重复元素的,如果在存储的时候逐个equals()比较,效率较低,哈希算法提高了去重复的效率,降低了使用equals()的次数
- 当HashSet调用add()方法存储对象的时候,先调用对象的hashCode()方法得到一个哈希值,然后集合中查找是否有哈希值相同的对象
- 如果没有哈希值相同的对象就直接存入集合
- 如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals()比较,返回false就存入,true就不存
TreeSet
- TreeSet是使用二叉树的原理的add()的对象进行按照指定的顺序排序,每增加一个元素,就会排一次序,插入到二叉树指定的位置
Integer
和String
对象都可以进行默认的 TreeSet 排序,而自定义类的对象是不可以的, 自己定义的类必须实现Comparable
接口,并且覆盖相应的compareTo()
函数,才可以正常使用- 在覆写 compare()函数时,要返回相应的值才能使 TreeSet 按照一定的规则来排序
- 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数
Map
HashMap
- HashMap 根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。
- HashMap 最多只允许一条记录的键为 null,允许多条记录的值为 null。
- HashMap 非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections 的 synchronizedMap 方法使HashMap 具有线程安全的能力,或者使用 ConcurrentHashMap
HashTable
- 历史遗留类,很多功能跟HashMap类似,不同的是继承自Dictionary类,并且是线程安全的,不过并发性不如ConcurrentHashMap,不建议使用
TreeMap
- 实现了SortedMap接口,内部可自动排序,默认按键的升序排序
- 在使用 TreeMap 时,key 必须实现 Comparable 接口或者在构造 TreeMap 传入自定义的Comparator,否则会在运行时抛出 java.lang.ClassCastException 类型的异常。
ConcurrentHashMap
- 线程安全的高并发HashMap