什么是集合
集合和数组一样,保存一组元素,提供了操作元素的方法
java.util.Collection是所有集合的顶级接口
Collection下面有两个常见的子接口:
- java.util.List:线性表 .可重复集合, 并且有序.
- java.util.Set: 不可重复的集合,大部分实现类是无序的.
判定重复元素的标准是依靠元素自身equals比较的结果.为true就认为是重复元素.
方法:
1.boolean add(E e)
向当前元素添加一个元素,元素添加成功返回true
E 参数 e 元素名(类别变量名)
2.int size()
返回当前元素的个数
3.boolean isEmpty()
判断当前集合是否是空集(不包含如何元素)
空集是有集合无元素,null是没有集合
4.void clear()
清空集合
集合与元素equals方法相关的方法
1.自己定义的类,(需要重写toString)集合输出的元素是元素重写toString 后的内容,不重写,返回的是地址(元素是引用类型),java自己定义的类都自己重写了(集合的toString会调用每个元素的toString方法体现出来)-----重写toString方法
集合重写了Object的toString方法,输出的格式为:
[元素1.toString(), 元素2.toString(), ....]
2.boolean contains(Object o)---重写equals方法
判断当前集合是否包含给定元素,这里判断的依据是给定元素是否与集合
现有元素存在equals比较为true的情况。
3.boolean remove(Object o)----重写equals方法
remove用来从集合中删除给定元素,删除的也是与集合中equals比较
为true的元素。
注意,对于可以存放重复元素的集合而言,只删除一次
集合存放的是元素的引用
集合只能存放引用类型元素,并且存放的是元素的引用(地址)
存放基本类的包装类:包装类名.valueof(基本类型)
c.add(Integer.valueof(1));
方法(Collection :ArrayList /HashSet)
1.boolean addAll(Collection c)
将给定集合所有元素添加到当前集合中(取并集)
当前集合若发生了改变,则返回true
2.boolean containsAll(Collection c)---全包含
判断当前集合是否包含给定集合中的所有元素---全包含
3.boolean removeAll(Collection c)
删除当前集合中与给定集合中的共有元素(删交集)
集合的遍历
Collection提供了统一的遍历集合方式:
迭代器 Iterator iterator()
java.util.Iterator 迭代器接口 定义迭代器遍历集合的相关操作
步骤:问 取 删(删除元素不是必要操作)
迭代器提供的相关方法:
boolean hasNext()------问
判断集合是否还有元素可以遍历
E next()-------取
获取集合的下一个元素(第一次调用时时获取第一个元素)
注意:集合默认的元素类型是Object(集合放相同类型的元素)
public class IteratorDemo {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("one");
c.add("two");
c.add("three");
System.out.println(c);
//获取迭代器
Iterator it = c.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
System.out.println(c);
}
}
迭代器遍历过程中不得通过集合的方法增删元素
否则会抛出异常:ConcurrentModificationException
public class IteratorDemo {
public static void main(String[] args) {
Collection c = new ArrayList ();
c.add("one");
c.add("#");
c.add("two");
c.add("#");
c.add("three");
System.out.println(c);
//获取迭代器
Iterator it = c.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
if("#".equals(str)){
// c.remove(str);------集合方式删除元素
/*
迭代器的remove方法可以将通过next方法获取的元素从集合
中删除。
*/
it.remove();-----迭代器方式删除元素
}
}
System.out.println(c);
}
}
增强型for循环
JDK5之后 也称新循环 ,java编译器认可,虚拟机不认可
for(元素类型 变量名:集合或数组 ){
循环体 }
//数组
String[] array = {"one","two","three","four","five"};
for(int i=0;i<array.length;i++){
String str = array[i];
System.out.println(str);
}
for(String str : array){
System.out.println(str);
}
//集合
Collection c = new ArrayList();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
//迭代器遍历
Iterator it = c.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
//新循环遍历
for(Object o : c){//数组本身默认的Object
String str = (String)o;//造型
System.out.println(str);
}
泛型
泛型也称为参数化类型,(JDK5以后)
允许我们在使用一个类时指定它当中属性,方法参数或返回值的类型.
- 泛型在集合中被广泛使用,用来指定集合中的元素类型.
- 有泛型支持的类在使用时若不指定泛型的具体类型则默认为原型Object
* Collection接口的定义
* public interface Collection<E> ... {
* Collection<E> 这里的<E>就是泛型
* Collection中add方法的定义,参数为E
* boolean add(E e)
Collection<String> c = new ArrayList<>();
c.add("one");//编译器会检查add方法的实参是否为String类型
c.add("two");
c.add("three");
c.add("four");
c.add("five");
// c.add(123);//编译不通过
//迭代器遍历
//迭代器也支持泛型,指定的与其遍历的集合指定的泛型一致即可
Iterator<String> it = c.iterator();
while(it.hasNext()){
//编译器编译代码时会根据迭代器指定的泛型补充造型代码
String str = it.next();//获取元素时无需在造型
System.out.println(str);
}
List集合常见方法
list是Collection下的集合
java.util.List 接口 继承自 Collection,是所有List的接口
java.util.ArrayList:内部由数组实现,查询性能好
java.util.LinkList 内部由链表实现,增删性能好
List集合的特点:可存放重复元素,并且有序,提供了通过下标操作元素的方法
1.E get(int index)获取指定下标对应的元素
String e = list.get(2);
2.E set(int index,E e)将给定元素设置到指定的位置,返回值是给位置原来的元素(替换元素)
String old = list.set(1,"six");
3.void add(int index,E e)将给定元素插入到指定位置
list.add(2,"six");
4.E remove(int index)删除并返回指定位置上的元素
String e = list.remove(1);
5.List subList(int start,int end) 获取当前集合指定范围内的子集,(含头不含尾)
//获取3-7这部分
List<Integer> subList = list.subList(3,8);
注意:对子集元素的操作就是对原集对应元素的操作
集合与数组的转换
1.集合转换为数组
方法:
Object[] array=list.toArray()
重载的toArray方法要求传入一个数组,内部会将集合所有元素存入该数组
后将其返回(前提是该数组长度>=集合的size)。如果给定的数组长度不足,
则方法内部会自行根据给定数组类型创建一个与集合size一致长度的数组并
将集合元素存入后返回。
String[] array = list.toArray(new String[list.size()]);
2.数组转换为LIst集合
数组的工具类Arrays提供了一个静态方法asList(),可以将一个数组转换为一个List集合
String[] array = {"one","two","three","four","five"};
System.out.println(Arrays.toString(array));//若直接输出输出的是地址
List<String> list = Arrays.asList(array);
System.out.println(list);
list.set(1,"six");
System.out.println(list);
//数组跟着改变了。注意:对数组转换的集合进行元素操作就是对原数组对应的操作
System.out.println(Arrays.toString(array));
/*
由于数组是定长的,因此对该集合进行增删元素的操作是不支持的,会抛出
异常:java.lang.UnsupportedOperationException
*/
// list.add("seven");
*
所有的集合都支持一个参数为Collection的构造方法,作用是在创建当前
集合的同时包含给定集合中的所有元素
*/
List<String> list2 = new ArrayList<>(list);
System.out.println("list2:"+list2);
list2.add("seven");
System.out.println("list2:"+list2);
集合的排序
java.util.Collection类
Collections是集合的工具类,里面定义了很多静态方法用于操作集合.
Collections.sort(List list)方法
可以对List集合进行自然排序(从小到大)
List<Integer> list = new ArrayList<>();
Random random = new Random();
for(int i=0;i<10;i++){
list.add(random.nextInt(100));
}
System.out.println(list);
Collections.sort(list);
System.out.println(list);
排序自定义类型元素
Collections.sort(List list)该方法要求集合中的元素类型必须实现接口:
Comparable,该接口中有一个抽象方法compareTo,这个方法用来定义元素之间比较
大小的规则.所以只有实现了该接口的元素才能利用这个方法比较出大小进而实现排序
操作.
实际开发中,我们并不会让我们自己定义的类(如果该类作为集合元素使用)去实现Comparable接口,因为这对我们的程序有侵入性.
侵入性:当我们调用某个API功能时,其要求我们为其修改其他额外的代码,这个现象就是侵入性.
侵入性越强的API越不利于程序的后期可维护性.应当尽量避免.
重载的Collections.sort(List list,Comparator c)方法
List<Point> list = new ArrayList<>();
list.add(new Point(1, 2));
list.add(new Point(15, 2));
list.add(new Point(9, 5));
list.add(new Point(6, 2));
list.add(new Point(5, 2));
list.add(new Point(3, 2));
System.out.println(list);
//没有侵入性的写法
Collections.sort(list, new Comparator<Point>() {
@Override
/*
* 实现比较器接口后必须重写方法compare.
* 该方法用来定义参数o1与参数o2的比较大小规则
* 返回值用来表示o1与o2的大小关系
*/
public int compare(Point o1, Point o2) {//默认了正序,倒写就是倒序
int len1= o1.getX() * o1.getX() + o1.getY() * o1.getY();
int len2= o2.getX() * o2.getX() + o2.getY() * o2.getY();
return len1 - len2;
}
});
//没有侵入性写法
// 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);
System.out.println(list);
排序
Collections.sort(list);//排序(正序)
Collections.shuffle(list);//乱序
Collections .sort(list,(i1,i2)->i2-i1);//倒序
排序字符串
java中提供的类,如:String,包装类都实现了Comparable接口,但有时候这些比较规则不能满足我们的排序需求时,同样可以临时提供一种比较规则来进行排序.
List<String >list=new ArrayList<>();
list.add("曹操");
list.add("李明德");
list.add("东野圭吾");
System.out.println(list);
// Collections.sort(list, Comparator.comparingInt(String::length));
Collections.sort(list,(s1,s2)->s2.length()-s1.length());
System.out.println(list);