数组的长度是固定的,在很多情况下,一组数据的数目是不固定的,为了使程序能方便的存储和操纵数目不固定的一组数据,JDK的API中提供了集合,所有的集合类都位于java.util包中,与数组不同,集合不能存放基本数据类型,而只能存放对象的引用(通常会直接描述为集合中存放的对象)
集合的特点:
1.可存放不同类型的对象(必须是对象)
数组只能存放同一类型数据,但是可以存放基本类型数据
2.集合的长度可以自动增加
数组的长度一旦确定,就不能再改变
3.集合对象中有众多方法可以直接调用进行元素(数据)操作
数组对象中没有方法可以对数据进行操作
4.java.util包中的辅助工具类Colletions,也能对集合中的元素进行操作
java.util包中的辅助工具类Arrays,是用来对数组中的元素进行操作的。
1)Iterable接口
实现这个接口对象,可以使用"foreach"语句对其进行循环遍历。并且该接口中提供了一个方法可以返回一个迭代器对象,迭代器对象在这里的作用就是循环遍历集合中的每一个元素。
public Iterator iterator();
2)Collection接口
Collection接口继承了Iterable接口。
Collection类型集合体系结构中的根接口,JDK中不提供此接口的任何直接实现,而是提供更具体的子接口(List和Set)。
Collection接口中提供了很多集合中通用的方法。
例如:
add方法
remove方法
clear方法
size方法
....
注:JDK5以上的自动装箱拆箱
3)Collection类型集合的遍历
1.通用方式: 使用集合中提供的迭代器
Collection c = new ..;(List或Set类型都可以)
//调用add方法存数据
Iterator iterator = c.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
2.List集合的特有方式:get方法通过下标访问元素
(注:Set集合不能这样使用)
List list = new ArrayList();
//调用add方法存数据
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
3.foreach循环(增强for循环)
注:JDK5.0版本及以上可用
Collection c = new ..;(List或Set类型都可以)
//调用add方法存数据
//自动遍历集合c中的元素,并且每次使用变量o来接收
for(Object o:c){
System.out.println(o);
}
注:foreach循环也可以遍历数组
4)List接口和Set接口
List和Set都是Collection接口的子接口,但他们各自的特点不同
List类型集合特点:集合中的元素有序且可重复
Set类型集合特点 :集合中的元素不可重复,有没有序要看Set接口具体的实现类是谁。
注:有序指的是元素放到集合中的顺序和循环遍历出来的顺序一致
List接口常见的实现类有:ArrayList,LinkedList,Vector等
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构
2.对于数据的随机访问,ArrayList效率优于LinkedList,因为LinkedList要移动指针
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据
4.Vector是线程安全的集合,但是速度慢
5.查看API可知,List接口中是这些集合中共有的方法,而且每个集合类中又有一些自己独有的方法。
Set接口常见的实现类有:HashSet,LinkedHashSet
1.HashSet集合中元素的特点:无序不可重复
2.LinkedHashSet集合中元素的特点:有序不可重复
5)SortedSet接口和TreeSet类
SortedSet接口是Set接口的子接口,除了拥有Set集合的一些基本特点之外,还提供了排序的功能。
TreeSet类就是SortedSet接口的实现类
6)TreeSet类的排序功能
注:TreeSet排序永远都是从小到大排,但是谁大谁小是我们的方法说了算的
1.自然排序
核心:让元素自身具备比较性,需要实现Comparable接口,重写其compareTo方法,比较出大小后即可进行排序
java.lang.Comparable接口
例如:
public class Student implements Comparable{
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int compareTo(Object o) {
Student s = (Student)o;
if(this.id<s.id){
return -1;
}
else if(this.id>s.id){
return 1;
}
return 0;
}
}
注:
s1.compareTo(s2);
返回正数说明s1大
返回负数说明s1小
返回0说明s1和s2相等
2.比较器排序(定制排序、客户化排序)
核心:使用比较器进行元素之间的比较,比较出大小后即可进行排序。
java.util.Comparator接口
例如:
main:
Set set = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Student s1 = (Student) o1;
Student s2 = (Student) o2;
return (int)(s1.getId()-s2.getId());
}
});
注:比较器排序的优先级比自然排序的高
思考:在TreeSet中整数默认是从小到大排序,字符是默认是按a-z的顺序,那么怎让它们的顺序是倒过来的?(给比较结果添加负号)
7)Collection类型集合与数组之间的转换
Collection接口中定义了俩个方法,可以将当前集合转换为数组:
Object[] toArray() 返回包含集合中所有元素的数组
例如:
Collection c = new ...;(List或者Set的实现类都可以)
Object[] array = c.toArray();
System.out.println(Arrays.toString(array));
<T> T[] toArray(T[] a) 可指定返回数组的类型
例如:
Collection c = new ...;(List或者Set的实现类都可以)
String[] str = new String[set.size()];
//元素自动存放到数组str中了
set.toArray(str);
System.out.println(Arrays.toString(str));
java.util.Arrays中定义了一个方法,可以将数组转换为List类型集合
public static <T> List<T> asList(T... a)
例如:
Integer[] a = new Integer[4];
a[0] = 12;
a[1] = 13;
a[2] = 14;
a[3] = 15;
List list = Arrays.asList(a);
for(Object o:list){
System.out.println(o);
}
输出结果:
12
13
14
15
例如:
int[] a = new int[4];
a[0] = 12;
a[1] = 13;
a[2] = 14;
a[3] = 15;
List list = Arrays.asList(a);
for(Object o:list){
System.out.println(o);
}
输出结果:
[I@3cf5b814
注意基本类型数组和引用类型数组在这里的区别
8)Collection类型集合的工具类:Collections
注意Collection和Collections的区别: 一个是接口一个是类
java.util.Collections类是一个工具类,类中提供了很多的静态方法对Collection类型的集合进行操作
fill方法,使用指定元素替换指定列表中的所有元素。
例如:
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
Collections.fill(list, 20);
for(Object o:list){
System.out.println(o);
}
max方法,根据元素的自然顺序,返回给定集合的最大元素
例如:
List list = new ArrayList();
list.add(1);
list.add(9);
list.add(3);
System.out.println(Collections.max(list));
min方法,根据元素的自然顺序,返回给定集合的最小元素
reverse方法,反转集合中的元素
例如:
List list = new ArrayList();
list.add(1);
list.add(9);
list.add(3);
Collections.reverse(list);
for(Object o:list){
System.out.println(o);
}
sort方法,根据元素的自然顺序,对指定列表按升序进行排序
例如:
List list = new ArrayList();
list.add(1);
list.add(9);
list.add(3);
Collections.sort(list);
for(Object o:list){
System.out.println(o);
}
shuffle方法,使用默认随机源对指定列表进行置换
例如:
List list = new ArrayList();
list.add(1);
list.add(9);
list.add(3);
Collections.shuffle(list);
for(Object o:list){
System.out.println(o);
}
还有一系列的方法,可以把集合转为相应的线程安全的集合对象
synchronizedList
synchronizedSet
synchronizedMap
9)Map接口
Map类型的集合与Collection类型的集合不同,Map类型的集合存储数据的时候,要使用Key-Value的形式(键值对),且Key值不能重复,否则会覆盖原来的键值对
Map接口中的一些方法
put方法
get方法
clear方法
containsKey方法
containsValue方法
isEmpty方法
remove方法
size方法
10)Map接口的常用实现类
HashMap类和Hashtable类
1.HashMap是线程不安全的,Hashtable是线程安全的
2.HashMap允许key值或者value值为null,但是Hashtable中的key值或者value值都不允许为null,否则报错.
11)Map类型集合的遍历
1.使用keySet方法,可以返回该Map集合中所有key值的set类型集合
例如:
Map map = new HashMap();
//调用put方法存值
for(Object key:map.keySet()){
System.out.println(key+" : "+map.get(key));
}
2.使用values方法,可以返回该Map集合中所有value值的Collection类型集合
例如:
Map map = new HashMap();
//调用put方法存值
for(Object value:map.values()){
System.out.println(value);
}
3.使用entrySet方法,可以返回该Map集合中,包含所有Entry类型对象的Set集合
Set<Map.Entry<K,V>> entrySet();
注:Entry是声明Map接口中的内部接口(看API或源码可知),一个Entry类型对象就表示Map中的一组键值对(K-V)
例如:
Map map = new HashMap();
//调用put方法存值
Set entrySet = map.entrySet();
for(Object obj:entrySet){
Entry entry = (Entry)obj;
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
注意这里导入Entry接口的形式。
12)SortedMap接口和TreeMap类
SortedMap接口是Map的子接口,其进一步提供对于键的排序功能。
TreeMap类就是SortedMap接口的实现类。
TreeMap可以对key值进行自然排序或者比较器排序,其用法和TreeSet是一致的。