集合java.util.Collection
集合时一组数据结构,与数组一样,用来保存一组元素
集合提供了一系列操作元素的方法,使用更方便.
Collection是所有集合的顶级接口,规定了所有集合都应当具备的方法.
有两个常用的派生接口:
java.util.List:可重复集且有序
java.util.Set:不可重复集
元素是否重复是依靠元素自身的equals比较
boolean add(E e)
向当前集合中添加给定元素,当该元素成功添加则返回true
由于set集合是不可重复的,所以添加重复元素是会返回false的,List集合不存在此种情况
int size()
返回当前集合的元素个数
boolean isEmpty()
集合提供了判断是否包含给定元素的方法
boolean contains(E e)
若集合包含当前元素则返回true,否则返回false
contains方法会用参数对象u集合现有的元素顺序及逆行equals比较,若头返回值为true,则认为集合包含该元素,所以元素自身的equals方法直接决定估计和判断包含该元素的结果
boolean remove(E e)
从集合中删除给定元素,只删除一个
删除也是删除集合中关于给定 元素equals比较为true的元素,对于list而言,重复元素只删除第一个
集合间的操作
boolean addAll(Collection c) 取并集
添加完毕后,当前集合元素发生改变中则返回true
boolean contains(Collection c)
判断当前集合是否包含给定集合中 的所有元素
boolean removeAll(Collection c)
删除交集
集合的遍历
Collection提供了统一的遍历集合的方式:迭代器模式
对应方法:
Iterator iterator()
该方法可以返回一个用户遍历当前集合的迭代器
java.util.Iterator接口
迭代器接口规定了迭代器遍历集合的相关操作,遍历方式应当遵循:问,取,删的过程.
而删除元素操作不是必须操作.不同的集合都实现了一个可以遍历自身的迭代器实现类,我们无需己住实现类的名字,
只要当它为Iterator并操作即可(多态)
//获取迭代器
Iterator it = c.iterator();
/*
* boolean hasNext()
* 判断集合是否还有下一个元素可以迭代//问的过程
*/
while(it.hasNext()){
/*
* E next()
* 通过迭代器获取集合的下一个元素//取的过过程
*/
System.out.println(it.next());
}
迭代器的删除操作it.remove()
在遍历的过程中进行删除操作:
需要注意:迭代器有一个要求,就是在遍历的而过程中不得使用集合的方法进行元素的增删,否则会抛出异常.但是可以通过迭代器自身提供的remove方法删除元素.该方法不需要传入参数,删除的是通过next方法取出来的元素.
while(it.hasNext()){
String str = (String) it.next();
if("##".equals(str)){
//c.remove(str);并发修改异常,集合遍历的过程中不允许通过集合的增删方法对集合进行操作,只能通过迭代器自身的remove()方法删除元素
it.remove();
}
}
集合在遍历的过程中不允许通过集合的方法增删元素
ConcurrentModificationException 并发修改异常
JDK1.5之后退出了一个特性:增强型for循环
也称为新循环或for each
新循环就是用来遍历集合或数组使用的,所以功能上不去带传统的for循环工作,并且该特性是编译器认可,而非虚拟机认可,编译器最终会讲使用新循环遍历改为传统遍历方式.(数组for,集合为Iterator)
新循环遍历集合最终被编译器改变为迭代器遍历,所以在使用新循环遍历集合的过程中不要通过集合的方法增删元素
for(元素数据类型 变量 : 数组或者需要遍历的集合){
使用变量即可
}
集合遍历时需要用Object接收,然后进行强转
for(Object o : c){//集合只能用Object接收
String str = (String) o;
System.out.println(str);
}
泛型(编译器认可)
泛型是JDK1.5之后推出的另一个新特性,泛型也称为参数化类型,指在使用某个类时为其属性,方法参数,方法返回值的类型指定实际类型.这在实际开发中可以大大提高代码的灵活度.
泛型应用最广的地方就是集合,用来约束集合的元素类型.泛型的世纪类型为Object,当不指定泛型时,默认就会使用原型Object.
//创建集合时通过泛型约束集合的元素类型
Collection<String> c = new ArrayList<String>();
c.add("one");//此时集合中只能存放String
c.add("two");
c.add("three");
c.add("four");
//c.add(1);
System.out.println(c);
//获取迭代器时也可以通过泛型告知迭代器元素类型
Iterator<String> it = c.iterator();
while(it.hasNext()){
//获取元素时不需再造型
String str = it.next();
System.out.println(str);
}
for (String str : c) {
System.out.println(str);
}
泛型可以允许调用者在使用时决定一个类中属性,参数,返回值等的类型,从而提高代码的灵活性
Type<Integer> t1 = new Type<Integer>(1, 2);
//编译器会检查实际参数类型是否符合泛型要求
t1.setX(3);
//编译器会自动补充造型回Integer的代码 int x1 =((Integer)t1.getX()).intValue();
//int x1 =((Integer)t1.getX()).intValue();
int x1 = t1.getX();
System.out.println("x1 :" + x1);
System.out.println("t1 "+t1);
//当不指定泛型时,编译器的默认泛型为原型Object
Type t2 = t1;
System.out.println("t2 " + t2);
t2.setX("一");
System.out.println("t2 " + t2);
//类造型异常
x1 = t1.getX();
System.out.println("x1 " + x1);
System.out.println("t1 " + t1);
List
java.util.List 接口
List是Collection的子接口,规定了List方法的相关功能
List集合的特点:可重复,并且有序..提供了一组通过下标操作元素的额方法
常用实现类:java.util.ArrayList:内部由十足实现,查询效率高,但是增删元素效率差
在对元素操作效率没有特别苛刻要求时,通常使用的时ArrayList这个集合
List提供了重载的add,remove
/*
* void add(int index,E e)
* index <= size
* 将元素e插入到下标为1的位置
*/
list.add(4, "2");
/*
* E remove(int index)
* 删除下标为index的元素并返回
*/
String remove = list.remove(0);
System.out.println("删除的元素:" + remove);
System.out.println("删除下标元素" + list);
List提供的一组通过下标操作元素的方法
/*
* E get(int index)
* 0 <= index < size
* 获取指定位置对应的元素
*/
String str = list.get(4);
System.out.println(str);
/*
* ArrayList底层是数组,可以使用普通遍历
*/
for(int i = 0 ; i < list.size() ;i++){
str = list.get(i);
System.out.println(str);
}
/*
* E set(int index , E e)
* 将给定元素设置到指定位置,返回值为原位置对应的元素(替换元素操作)
*/
System.out.println(list);
String old = list.set(1, "2");
System.out.println("被替换的元素为:" + old);
System.out.println(list);
获取子集操作
对子集元素的操作就是对元集合对应元素的操作
/*
* List subList(int startIndex,int endIndex)
* 获取list集合下标为[startIndex,endIndex)的子集合
*/
List<Integer> subList = list.subList(3, 8);
System.out.println("list.subList(3, 8):" + subList);
// 将子集元素扩大十倍
for (int i = 0; i < subList.size(); i++) {
subList.set(i, subList.get(i) * 10);
}
System.out.println("扩大十倍的subList:"+subList);
System.out.println(list);
/*list删除2-8*/
list.subList(2, 8).clear();
集合和数组的互转
集合转换为数组操作
Collection提供了一个方法:toArray;该方法可以将当前集合转换为一个数组
//Object[] array = c.toArray();不常用
/*
* 此处new String[len],当这个数组可以存下集合中的元素时,就使用这个数组存,不满的为null
* 若存不下,则它自己创建一个数组存
*/
int len = c.size();
String[] array = c.toArray(new String[9]);
System.out.println(array.length);
for(int i = 0 ;i < array.length ;i++){
System.out.println(array[i]);
}
数组转成集合
数组的工具类:Arrays提供了一个静态方法:asList
可以将一个数组转换为一个List集合,而且只能是List集合,原因在于,List集合是可以重复的
数组转换过来的集合,对该集合操作就是对原数组操作
String[] array = {"one", "two", "three", "four"};
List<String> list = Arrays.asList(array);
System.out.println(list);
/*
* 对数组转换而来的集合进行操作就是对原数组进行对应的元素进行操作
*/
list.set(0, "1");
System.out.println("替换后的list:" +list);
System.out.println("array:" + Arrays.toString(array));
/*
* 数组转换而来的集合增删元素会导致数组扩容或者缩容,而数组本身是定长的,
* 所以既然数组转换的集合表示该数组,那么久不能增删元素,否则会抛异常
* UnsupportedOperationException.
*/
//list.add("five");//UnsupportedOperationException
/*List<String> list2 = new ArrayList<String>();
list2.addAll(list);*/
/*
* 所有集合都提供了一个参数为Collection类型的构造方法,作用是再创建
* 当前集合的同时包含给定集合中的所有元素,所以下面这个实例化过程就等同于上两步.
*/
List<String> list2 = new ArrayList<String>(list);
list2.add("five");