1. Collection
Collection是整个集合框架的基础,作用只是提供维护一组对象的基本接口。
1.1 创建集合
父类引用指向子类对象
Collection<元素类型> 变量名=new ArrayList<元素类型>();//只可存储<>指定的类型
Collection 变量名=new ArrayList();//集合元素默认为Object,任何元素类型都可存储
1.2 求元素个数
size():返回Collection中元素的个数
- length:数组的属性,返回数组中元素个数
- length():字符串的方法,返回其中元素个数
1.3 遍历方式
通用获取方式:
- 判断集合中有没有元素
- 有,取出,回1——迭代
- 没有,结束
1、无get方法,得用Object[] toArray(),转换为数组后,才可用get();
2、iterator(),可返回一个迭代器对象,可通过迭代对象来迭代集合。
1.4 常用方法
boolean add(E e)
void clear()
boolean contains(Object o)
boolean remove(Object o)
boolean isEmpty()
int size()
Object[] toArray()
Iterator<E> iterator()
1.5 注意
- 集合中存放的其实是对象的地址
- 集合中存基本数值时,都自动装箱了
- 存储时,提升为了Object,取出时要使用元素的特有内容时,应向下转型。
- 如果集合中存储的是多种对象,此时进行向下转型是会发生类型转换异常ClassCastException
2. 迭代器
Iterator是一个对象,工作是遍历并选择序列中的对象。创建代价小,又称为轻量级的容器。
2.1使用步骤
- 使用本容器的iterator()返回一个Iterator,然后通过Iterator的next()返回第一个元素;
- 使用Iterator的hasNext()判断容器中是否还有元素,如果有,可以使用next()获取下一个元素;
- 可以通过remove()删除迭代器返回的元素。
2.2 ListIterator
ListIterator只存在于List中,可用List.ListIterator()获取
支持在迭代器件向List中添加或删除元素,并且可以在List中双向滚动。
2.3区别
Iterator和ListIterator的区别:
- Iterator只能正向遍历集合,适用于获取移除元素;
- ListIterator继承自Iterator,专门针对List,可以从两个方向来遍历List,同时支持元素的修改
2.3 使用
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
Collection c=new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
if(c.contains("java"))
c.add("android");
for(Iterator it=c.iterator();it.hasNext();) {
System.out.println(it.next());
}
}
}
运行结果
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
Collection c=new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
Iterator it=c.iterator();
while(it.hasNext()) {
String s=(String)it.next();
if(s.equals("java"))
c.add("android");
}
for(Iterator is=c.iterator();is.hasNext();) {
System.out.println(is.next());
}
}
}
出错:
并发修改异常。这通常是由于使用Iterator遍历容器的同时又对容器做增加或删除操作导致的,或者由于多线程操作导致,当一个线程使用迭代器遍历容器的同时,另外一个线程对这个容器进行增加后删除操作。
主要原因:当容器调用iterator()返回Iterator对象时,把容器中的包含对象的个数赋值给了一个变量expectedModCount,在调用next()时会比较变量expectedModeCount与容器中实际对象的个数modCount是否相等,若二者不等,则会抛出ConcurrentModificationException。
解决方法:在遍历过程中把需要删除的对象保存在一个集合中,等遍历结束后再调用removeAll()来删除,或者使用iter.remove()。
多线程情况的解决方法:
- JDK 1.5引入了线程安全的容器,比如ConcurrentHashMap和CopyOnWriteArrayList。可以使用这些线程安全的容器替代费线程安全的容器。
- 在使用迭代器遍历容器时对容器的操作放在synchronized代码块中,但是当引用程序并发程度比较高时,这会严重影响程序性能。
2.4 增强for循环
for(数据类型 变量名:数组或集合){
....
}
int[] arr={3,1,0,9};
for(int i:arr){
System.out.println(i+1);
}
将arr中的元素值赋给i,i+1改变的是i的值,不是arr中元素的值。
好处:代码少,方便对容器的遍历;
缺点:无索引,不可操作容器内的元素。
在增强for中不能修改集合,否则会发生并发修改异常——增强for底层是迭代器
3. Collections
此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。
如果为此类的方法所提供的 collection 或类对象为 null,则这些方法都将抛出 NullPointerException。
3.1 Collection和Collections
Collection:结合体系的最顶层,包含了集合体系的共性
Collections:一个工具类,构造方法私有,方法为static,用于操作Collection
3.2 常用方法
static int binarySearch(List list,T key):使用二分搜索法搜索指定列表,以获得指定对象在指定列表中地索引。
- 前提:list有序,
static void copy(List des,List src): 将所有元素从一个列表复制到另一个列表。
- 目标列表的长度至少等于源列表
static void fill(List list,T obj):使用指定元素替换指定列表中的所有元素。
static void reverse(List list):反转指定列表中元素的顺序。
static void shuffle(List list):使用默认随机源对指定列表进行置换。
static void sort(List list): 根据元素的自然顺序对指定列表按升序进行排序。
static void swap(List list,int i,int j):在指定列表的指定位置处交换元素。
返回值为void,说明备操作对象本身发生了变化
返回值为一个新对象,说明被操作的对象一般不会发生变化。(特殊:Buffer的append())
4. 泛型
用来灵活地将数据类型应用到不同的类、方法和接口中。
将数据类型作为参数传递。
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
4.1 定义格式
修饰符 class 类名<代表泛型的变量>{ }
ArrayList<String>——编译时限制
arr.add(arg)
若arg是String类型,编译成功;
若不是,编译失败
但编译后的class文件无泛型。——所以Java是伪泛型
可以保证安全性吗?——可以,因为不符合的数据类型,首先编译不会通过
4.2 使用格式
创建对象时,确定泛型的类型。
4.3 含有泛型的方法
定义: 修饰符 <代表泛型的变量> 返回值类型 方法名(参数){...}
使用:调用方法时,确定泛型的类型
4.4 好处
避免了类型转换的麻烦,将运行时的ClassCastException转移到了编译时期的编译失败。
4.5 泛型的通配
?:可匹配所有的数据类型
Collection<?> coll
Collection c=new ArrayList();——此处未规定泛型类型,所以是默认类型Object
此时使用增强for时,for(Object obj:数组或集合)