java的集合框架 java.util.Collection接口 Collection是所有集合的顶级接口,里面规定了集合操作元素的相关功能方法。 集合与数组一样,用于存储一组元素,但是集合有多个不同的实现类来实现不同的 数据结构。 Collection下面有两个常见的子接口: java.util.List:线性表,特点:可以保存重复元素并且有序,可通过下标操作。 java.util.Set:不可重复的集合 这里的重复元素判定是依靠元素自身equals方法比较的结果而定。 List常见的实现类: java.util.ArrayList,java.util.LinkedList Set常见的实现类: java.util.HashSet
数组 [ ] length 是反映数组能放多少个元素 定长
集合 没有容量,不表示长度,size随时变
方法
boolean add(E e)
向当前集合中添加一个元素,成功添加后返回true否则返回false
int size()
返回当前集合的元素个数
boolean isEmpty()
判断当前集合是否为空集,当集合的size为0时,isEmpty返回值为true
boolean contains(Object o)
判断当前集合是否包含给定元素
集合重写了toString方法,格式为:
[元素1.toString(), 元素2.toString(), ......]
集合的contains判断包含时的依据为:给定元素是否与集合中现有的元素
存在equals比较为true的情况,存在则认为包含。
remove方法删除元素时也是删除与集合中equals比较为true的元素
对于List集合而言,重复元素仅删除一次
clear() 清空集合
集合只能存放引用类型元素,并且存放的是元素的引用(地址)
集合之间的操作
boolean addAll(Collection c)
将给定集合中的所有元素添加到当前集合中
boolean containsAll(Collection c)
判断当前集合是否包含给定集合中的所有元素
removeAll删除当前集合中与给定集合的共有元素。
集合的遍历 Collection提供了一个方法: Iterator iterator() 该方法会返回一个用于遍历当前集合的迭代器实现类,使用它可以对集合进行遍历. java.util.Iterator接口:迭代器接口 迭代器接口中规定了遍历集合元素所需要的相关方法,使用迭代器遍历需要遵循的 原则为:问,取,删.其中删除元素不是遍历过程中的必要操作. 注:不同的集合实现类都提供了一个用于遍历自身的迭代器实现类,我们不需要知道 它们的名字,用多态的思想把他们看成Iterator进行操作即可.
JDK5推出时推出了一个新特性:泛型 泛型又称为参数化类型,允许我们在使用一个类的时候去指定它里面某属性 或方法的参数和返回值的类型.使得我们使用这个类时更符合我们需求. 泛型在集合中被大量使用,用于规定集合中的元素类型.
Collection<String> c = new ArrayList<>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
System.out.println(c);
/
迭代器也支持泛型,使用时指定的类型与集合元素类型一致即可.
/
Iterator<String> it = c.iterator();
/
boolean hasNext()
判断集合是否还有元素可以迭代
/
while(it.hasNext()){
/
E next()
获取集合下一个元素(第一次调用时是获取第一个元素,以此类推)
/
String str = it.next();
System.out.println(str);
if("#".equals(str)){
/
迭代器有一个要求,在遍历的过程中不能通过集合的方法增删
元素,否则会抛出异常
/
// c.remove(str);
/
迭代器提供的remove方法可以删除本次遍历出来的元素
/
it.remove();
}
}
System.out.println(c);
增强型for循环 JDK5推出时推出的一个新特性 它也称为:增强循环或新循环 新循环不取代传统for循环的工作,它只是用相同的语法去遍历集合或数组使用.
for(int i=0;i<array.length;i++){
}
新循环是编译器认可,而不是java虚拟机,编译器在编译源代码时
发现使用新循环遍历数组时,会将代码改为普通的for循环进行
for(String str : array){
System.out.println(str);
}
Collection<String> c = new ArrayList<>();
新循环遍历集合会被编译器改为迭代器遍历。
因此在使用新循环遍历过程中,仍然不能通过集合的方法增删元素
for(String str : c){
System.out.println(str);
}
java.util.List接口 List继承自Collection,是集合中非常常用的一个子类型。特点是:可以放重复元素并且有序,其提供了一套通过下标操作元素的方法。 常见实现类: java.util.ArrayList:内部使用数组实现,查询性能更好。 java.util.LinkedList:内部使用链表实现,增删元素性能更好,首尾增删元素 性能最佳。
E get(int index)
获取指定下标所对应的元素
E set(int index,E e)
将给定元素设置到指定位置,返回值为该位置原有元素
List提供了一对重载的add,remove方法
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
/*
void add(int index,E e)
将给定元素添加到指定位置,原位置及后续元素顺序向后移动
插入操作
*/
list.add(2,"3");
System.out.println(list);
//[one,two,3,four,five]
/*
E remove(int index)
删除并返回指定位置的元素
*/
String old = list.remove(3);
System.out.println(list);
System.out.println("被删除的元素是:"+old);
List subList(int start,int end)
获取当前集合中指定范围内的子集,当我们通过一个List集合获取到一个子集后,对这个子集的任何操作就是对原集合这段元素的操作
集合转换为数组 Collection提供了一个方法:toArray(),可以将当前集合转换为一个数组
Collection<String> c = new ArrayList<>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
System.out.println(c);
// Object[] array = c.toArray();
/*
T[] toArray(T[] array)
将当前集合转换为数组,该方法要求传入一个数组。如果该数组可用(数组
长度>=集合的size时)会将当前集合元素存入该数组后再将该数组返回。
如果不可用会创建一个与参数数组同类型并且长度与集合size一致的数组
并将元素存入后返回。
*/
String[] array = c.toArray(new String[c.size()]);
System.out.println(array.length);
System.out.println(Arrays.toString(array));
数组转换为集合 数组的工具类:Arrays提供了一个静态方法:asList,可以将一个数组转换为一个List集合
String[] array = {"one","two","three","four","five"};
System.out.println("array:"+ Arrays.toString(array));
List<String> list = Arrays.asList(array);
System.out.println("list:"+list);
list.set(1,"2");
System.out.println("list:"+list);
/*
通过数组转换而来的集合,对该集合的元素操作就是对原数组的操作
这一点需要特别注意!
*/
System.out.println("array:"+ Arrays.toString(array));
/*
由于数组是定长的,因此从数组转换的集合是不可以调用增删元素等
会影响数组长度的操作,否则会抛出异常:UnsupportedOperationException
*/
// list.add("six");
/*
如果想向集合中增删元素,需要自行创建一个集合,然后将原集合元素
导入到该集合中即可。
所有的集合都支持一个参数类型为Collection的构造方法,作用是在
创建当前集合的同时包含给定集合中的所有元素
*/
List<String> list2 = new ArrayList<>(list);
list2.add("six");
System.out.println(list2);
集合的排序
List<Integer> list = new ArrayList<>();
Random random = new Random();
for(int i=0;i<10;i++){
list.add(random.nextInt(100));
}
Collections.sort(list);
Collections.reverse(list);
System.out.println(list);
排序含有自定义类型元素的集合
public static void main(String[] args) {
List<Point> list = new ArrayList<>();
list.add(new Point(7,8));
list.add(new Point(6,4));
list.add(new Point(3,1));
list.add(new Point(7,9));
list.add(new Point(12,54));
list.add(new Point(1,2));
System.out.println(list);
/*
Collections.sort(List list)该方法对List集合进行自然排序
即:从小到大排序。但是该方法对集合有一个要求,元素必须实现了接口
Comparable,否则编译不通过。
该接口中有一个抽象方法要求实现类重写,用于定义该类元素之间的大小关系
java中很多常用的类都实现了它,比如String,包装类。
当我们调用一个方法,而这个方法反过来还要求我们为其修改其他地方的
代码(比如这里要求我们修改Point类去实现Comparable接口并重写方法),
这种现象称为侵入性,侵入性越高(改的代码越多)越不利。写程序应当尽量
避免侵入性。
*/
// Collections.sort(list);
/*
Collections提供了一个重载sort方法,要求再传入一个参数:比较器
Comparator是比较器接口,实现它就需要重写方法:compare来定义
两个要比较的元素的大小规则。通常我们直接以匿名内部类形式创建为
集合的排序使用。
该方法中compare方法的两个参数就是要比较的两个元素,方法返回值为
比较大小的关系,定义如下:
当返回值>0,表示参数o1比o2大
当返回值<0,表示参数o1比o2小
当返回值=0,表示o1与o2相等
*/
// Collections.sort(list,new Comparator<Point>(){
// public int compare(Point o1, Point o2) {
// return o1.getX()*o1.getX()+o1.getY()*o1.getY() -
// o2.getX()*o2.getX()-o2.getY()*o2.getY();
// }
// });
Collections.sort(list,(o1,o2)->
o1.getX()*o1.getX()+o1.getY()*o1.getY() -
o2.getX()*o2.getX()-o2.getY()*o2.getY()
);
System.out.println(list);
}
排序字符串
List<String> list = new ArrayList<>();
list.add("jack");
list.add("Lisa");
list.add("Tom");
list.add("Jerry");
System.out.println(list);
// Collections.sort(list);
Collections.sort(list,(o1,o2)->o2.length()-o1.length());
System.out.println(list);