一.Java集合概述
Java集合大致分为Set,List,Queue和Map四种体系。其中set代表无序,不可重复的集合;List代表有序,重复的集合;Map代表具有映射关系的集合,Queue代表一种队列集合实现。
java的集合类主要由两个接口派生而出:Collection和Map
二.Collection和Iterator接口
1.Collection接口是List,Set和Queue接口的父接口,该接口里定义的方法即可用于操作Set集合,也可用于操作List和Queue集合。
对于Set List Queue和Map四种集合,最常用的实现类分别是HashSet, TreeSet, ArrayList, ArrayDeque, LinkedList和HashMap,TreeMap等实现类。
import java.util.*;
public class CollectionTest
{
public static void main(String[] args)
{
Collection c = new ArrayList();
// 添加元素
c.add("孙悟空");
// 虽然集合里不能放基本类型的值,但Java支持自动装箱
c.add(6);
System.out.println("c集合的元素个数为:" + c.size()); // 输出2
// 删除指定元素
c.remove(6);
System.out.println("c集合的元素个数为:" + c.size()); // 输出1
// 判断是否包含指定字符串
System.out.println("c集合的是否包含\"孙悟空\"字符串:"
+ c.contains("孙悟空")); // 输出true
c.add("轻量级Java EE企业应用实战");
System.out.println("c集合的元素:" + c);
Collection books = new HashSet();
books.add("轻量级Java EE企业应用实战");
books.add("疯狂Java讲义");
System.out.println("c集合是否完全包含books集合?"
+ c.containsAll(books)); // 输出false
// 用c集合减去books集合里的元素
c.removeAll(books);
System.out.println("c集合的元素:" + c);
// 删除c集合里所有元素
c.clear();
System.out.println("c集合的元素:" + c);
// 控制books集合里只剩下c集合里也包含的元素
books.retainAll(c);
System.out.println("books集合的元素:" + books);
}
}
2.使用Java8增强的Iterator遍历集合元素
Iterator接口主要用于遍历Collection集合中的元素,Iterator对象也被称为迭代器。
public class IteratorTest
{
public static void main(String[] args)
{
// 创建集合、添加元素的代码与前一个程序相同
Collection books = new HashSet();
books.add("轻量级Java EE企业应用实战");
books.add("疯狂Java讲义");
books.add("疯狂Android讲义");
// 获取books集合对应的迭代器
Iterator it = books.iterator();
while(it.hasNext())
{
// it.next()方法返回的数据类型是Object类型,因此需要强制类型转换
String book = (String)it.next();
System.out.println(book);
if (book.equals("疯狂Java讲义"))
{
// 从集合中删除上一次next方法返回的元素
it.remove();
}
// 对book变量赋值,不会改变集合元素本身
book = "测试字符串"; //①
}
System.out.println(books);
}
}
3.使用foreach循环遍历集合元素
用foreach循环来迭代访问集合元素。
public class ForeachTest
{
public static void main(String[] args)
{
// 创建集合、添加元素的代码与前一个程序相同
Collection books = new HashSet();
books.add(new String("轻量级Java EE企业应用实战"));
books.add(new String("疯狂Java讲义"));
books.add(new String("疯狂Android讲义"));
for (Object obj : books)
{
// 此处的book变量也不是集合元素本身
String book = (String)obj;
System.out.println(book);
if (book.equals("疯狂Android讲义"))
{
// 下面代码会引发ConcurrentModificationException异常
books.remove(book); //①
}
}
System.out.println(books);
}
}
三.set集合
1…HashSet类
HashSet是Set接口的典型实现,HashSet按Hash算法来存储集合中的元素,因此具有很好的存取合查找性能。
1>.HashSet具有以下特点
不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
HashSet不是同步的 ,如果多个线程同时访问一个HashSet,必须通过代码来保证其同步。
集合元素值可以是null
2.TreeSet类
TreeSet是SortedSet接口的实现类,可以确保集合元素处于排序状态。
3.EnumSet类
一个专为枚举类设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,EnumSet的集合元素也是有序的,EnumSet以枚举值在Enum类内的定义顺序来决定集合元素的顺序。
不允许加入null元素
四.List集合
ArrayList和Vector作为List类的两个典型实现,两者区别在于ArrayList是线程不安全的,Vector是线程安全的,所以Vector的性能比ArrayList的性能要低。
五.Queue集合
1.PriorityQueue实现类
PriorityQueue是一个比较标准的队列实现类,保存队列元素的顺序并不是按加入队列的顺序,而是按队列元素的大小进行重新排序。从这个角度考虑其实已经违反了队列的基本规则:FIFO.
2.Deque接口与ArrayDeque实现类
Deque接口是Queue接口的子接口,代表一个双端队列。ArrayDeque是一个基于数组实现的双端队列。
import java.util.*;
public class ArrayDequeStack
{
public static void main(String[] args)
{
ArrayDeque stack = new ArrayDeque();
// 依次将三个元素push入"栈"
stack.push("疯狂Java讲义");
stack.push("轻量级Java EE企业应用实战");
stack.push("疯狂Android讲义");
// 输出:[疯狂Android讲义, 轻量级Java EE企业应用实战, 疯狂Java讲义]
System.out.println(stack);
// 访问第一个元素,但并不将其pop出"栈",输出:疯狂Android讲义
System.out.println(stack.peek());
// 依然输出:[疯狂Android讲义, 疯狂Java讲义, 轻量级Java EE企业应用实战]
System.out.println(stack);
// pop出第一个元素,输出:疯狂Android讲义
System.out.println(stack.pop());
// 输出:[轻量级Java EE企业应用实战, 疯狂Java讲义]
System.out.println(stack);
}
}
3.LinkedList实现类
LinkedList类是List接口的实现类,一个List集合,可以根据索引来随机访问集合中的元素。LinkedList还实现了Deque接口,可以被当成双端队列来使用,即可当作栈,也可以当作队列使用。
import java.util.*;
public class LinkedListTest
{
public static void main(String[] args)
{
LinkedList books = new LinkedList();
// 将字符串元素加入队列的尾部
books.offer("疯狂Java讲义");
// 将一个字符串元素加入栈的顶部
books.push("轻量级Java EE企业应用实战");
// 将字符串元素添加到队列的头部(相当于栈的顶部)
books.offerFirst("疯狂Android讲义");
// 以List的方式(按索引访问的方式)来遍历集合元素
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());
// 下面输出:[轻量级Java EE企业应用实战]
System.out.println(books);
}
}
使用List集合的建议:
1.如果需要遍历List集合元素,对于ArrayList,Vector集合,应该使用随机访问方法(get)来遍历集合元素,这样性能更好;对于LinkedList集合,则应该采用迭代器(Iterator)来遍历集合元素。
2.如果需要经常执行插入和删除操作,优先考虑LinkedList集合。
3.如果涉及多线程访问问题,考虑使用Collections将集合包装成线程安全的集合。
六.Map集合
Map接口下则有HashMap,LinkedHashMap, SortedMap,TreeMap, EnumMap等子接口和实现类。
1.HashMap和Hashtable实现类
Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现,所以HashMap比Hashtable的性能高一点,但如果多个线程访问同一个Map对象时,使用Hashtable实现类会更好,
Hashtable不允许使用null作为key和value,如果试图把null放进Hashtable中,将会引发NullPointerException异常,但HashMap可以使用null作为Key或value。
由于HashMap里的key不能重复,所以HashMap里最多只有一个key-value对的key为null,但可以有无数多个key-value对的value为null。
import java.util.*;
public class NullInHashMap
{
public static void main(String[] args)
{
HashMap hm = new HashMap();
// 试图将两个key为null的key-value对放入HashMap中
hm.put(null , null);
hm.put(null , null); // ①
// 将一个value为null的key-value对放入HashMap中
hm.put("a" , null); // ②
// 输出Map对象
System.out.println(hm);
}
}
2.使用Properties读写属性文件
Properties类是Hashtable类的子类,该对象在处理属性文件时特别方便,Properties类可以把Map对象和属性文件关联起来,从而可以把Map对象中的key-value对写入属性文件中。
import java.util.*;
import java.io.*;
public class PropertiesTest
{
public static void main(String[] args)
throws Exception
{
Properties props = new Properties();
// 向Properties中增加属性
props.setProperty("username" , "yeeku");
props.setProperty("password" , "123456");
// 将Properties中的key-value对保存到a.ini文件中
props.store(new FileOutputStream("abc.ini")
, "comment line"); //①
props.setProperty("gender", "female");
props.load(new FileOutputStream("abc.ini"));
// 新建一个Properties对象
Properties props2 = new Properties();
// 向Properties中增加属性
props2.setProperty("gender" , "male");
// 将a.ini文件中的key-value对追加到props2中
props2.load(new FileInputStream("a.ini") ); //②
System.out.println(props2);
}
}
七.操作集合的工具类:Collections
java提供了一个操作Set,List和Map等集合的工具类,Collections,该工具提供了大量方法对集合元素进行排序,查询和修改等操作,还提供了将集合对象设置为不可变,对集合实现同步控制等方法。
import java.util.*;
public class SortTest
{
public static void main(String[] args)
{
ArrayList nums = new ArrayList();
nums.add(2);
nums.add(-5);
nums.add(3);
nums.add(0);
System.out.println(nums); // 输出:[2, -5, 3, 0]
Collections.reverse(nums); // 将List集合元素的次序反转
System.out.println(nums); // 输出:[0, 3, -5, 2]
Collections.sort(nums); // 将List集合元素的按自然顺序排序
System.out.println(nums); // 输出:[-5, 0, 2, 3]
Collections.shuffle(nums); // 将List集合元素的按随机顺序排序
System.out.println(nums); // 每次输出的次序不固定
}
}