集合是一种容器,可以存储各类对象进去。所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
这个集合的作用看上去很像数组,同样是容器,那为什么要定义出集合呢,它与数组的区别在哪里?它有什么特点?
区别:
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
特点:
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型。
这样,就知道了集合出现的原因,接下来需要理解集合的框架的构成和分类:
从上图可以看出Collection接口是最主要的集合,其子接口List (列表),Set (集) 都有许多子类。同时还衍生出了Iterator迭代器和Map集合。
List:可存放重复元素,元素存取是有序的。
Set:不可以存放重复元素,元素存取是无序的。
List接口下的3个主要实现接口子类:
Vector:线程安全,但速度慢,已被ArrayList替代。
ArrayList:线程不安全,查询速度快。
LinkedList:链表结构,增删速度快。
取出LIst集合中元素的方式:
1. get(int index):通过脚标获取元素。
2. iterator():通过迭代方法获取迭代器对象。
下面用一个除去ArrayList集合中重复的元素为例,来说明集合的功能:
import java.util.*;
/*
目的:去除ArrayList集合中的重复元素。
*/
public class ArrayListTest
{
//打印方法简写
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java01");
al.add("java02");
al.add("java01");
sop(al); //除去重复元素前
al = singleElement(al);
sop(al); //除去重复元素后
}
public static ArrayList singleElement(ArrayList al)
{
//定义一个临时容器用了存储集合中的无重复元素
ArrayList newAl = new ArrayList();
Iterator it = al.iterator(); //迭代器
while(it.hasNext())
{
Object obj = it.next();
if(!newAl.contains(obj)) //当新集合中没有obj时,存储进来
newAl.add(obj);
}
return newAl;
}
}
这样就能除去集合中的重复元素了。对集合中元素的操作要比对数组中元素的操作更加方便,所以在Java中集合是最常用的方法。
Set接口下的2个主要实现接口子类:
HashSet:线程不安全,存取速度快。
TreeSet: 线程不安全,可以对Set集合中的元素进行排序。
Set集合能保证其中元素的唯一性,它是如何做到的呢:
1. 先用hashCode方法得到其元素的返回值,若与集合中的任一元素都不同,则储存进集合。
2. 若集合中有返回值相同的元素,则再用equals方法比较两个元素,返回值为true,则判定为同一元素,不储存进集合;返回值为false,则判定不为同一元素,储存进集合。
这样便保证了集合中元素的唯一性。
TreeSet的最大特点是其具有排序的功能,它的底层数据结构是二叉树,它有两种实现排序的方式:
1. 让元素自身具备比较性:
这需要元素实现comparable接口,并覆盖compareTo方法,这种方式称为元素的自然顺序。
2. 让集合具备比较性:
当元素本身不具备比较性的时候,后者具备的比较性不是我们所需要的时候,就需要自己定义一个类,实现Comparator接口,覆盖compare方法,在将这个比较器作为参数传递给TreeSet集合的构造函数。
下面是一个按人名长度比较的例子:
package test;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class Test7 {
public static void main(String[] args) {
//创建一个Person集合,并添加3个元素
Set<Person> s = new TreeSet<Person>(new StrlenComparator());
s.add(new Person("zhangsan"));
s.add(new Person("lisi"));
s.add(new Person("zhaoliu"));
//打印排序后的结果
for(Person p: s){
System.out.println(p.getName());
}
}
}
//定义Person类,必须初始化名字
class Person{
private String name;
Person(String name){
this.name = name;
}
public String getName(){
return name;
}
}
//自己定义个比较器,按照名字长度来排序
class StrlenComparator implements Comparator<Person>{
public int compare(Person p1, Person p2){
//长度短的放二叉树左边,长得放右边,一样长则比较两个名字是否相同,相同则判断为同一个元素
int num = p1.getName().length() - p2.getName().length();
if(num==0)
return p1.getName().compareTo(p2.getName());
else
return num;
}
}
打印结果按照定义的名字长度排序:
lisi
zhaoliu
zhangsan
可见对集合的操作各式各样,当我们需要什么功能时,便选择对应的集合来存储我们的元素,并对其进行想要的操作。
Map集合:
1. Map与Collection在集合框架中属并列存在
2. Map存储的是键值对
3. Map存储元素使用put方法,Collection使用add方法
4. Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素
5. Map集合中键要保证唯一性
Map集合的3个常用实现子类:
1. Hashtable:线程安全,速度慢,不允许存放null键,null值,已被HashMap替代
2. HashMap:线程不安全,速度快,允许存放null 键,null值
3. TreeMap:对键进行排序,排序原理与TreeSet 相同
特别需要注意的是:
Map中的元素取出方式只有2种:1. entrySet() 2. keySet()。
都是先转换成Set集合后再用Set集合的方式取出。
下面是一个用了这两种方式对Map集合操作的例子:
package test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Test8 {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("01","zhangsan1");
map.put("04","zhangsan4");
//将Map集合中的映射关系取出。存入到Set集合中。
Set<Map.Entry<String,String>> entrySet = map.entrySet();
Iterator<Map.Entry<String,String>> it = entrySet.iterator();
while(it.hasNext())
{
Map.Entry<String,String> me = it.next();
String key = me.getKey(); //映射关系中获取key,value的方法
String value = me.getValue();
System.out.println(key+":"+value);
}
/*
//先获取map集合的所有键的Set集合,keySet();
Set<String> keySet = map.keySet();
//有了Set集合。就可以获取其迭代器。
Iterator<String> it = keySet.iterator();
while(it.hasNext())
{
String key = it.next();
//有了键可以通过map集合的get方法获取其对应的值。
String value = map.get(key);
System.out.println("key:"+key+",value:"+value);
}
*/
}
}
因为集合方便操作,所以当我们需要对数组进行操作时可以转换成集合的形势,这样更加方便。当我们不想要其他人对集合中的元素进行操作时,也可以将集合转换为数组,以保证其安全性。
通过Arrays中的方法进行操作:
数组-->集合:Arrays.asList(T... a)
集合-->数组:
1. toArray(); 返回一个Object数组
2. toArray(T[] a); 返回指定的T数组