一.Iterator接口
java.util.Iterator
接口也是Java集合中的一员,只是它主要用于迭代访问集合中的元素,也就是遍历数据,而Collection和Map接口是用来存储数据。
Iterator接口也被称为迭代器,迭代器遍历的过程不能进行元素的增删操作。
增强for循环的内部原理使用的就是Iterator迭代器。
Iterator接口提供了以下几个常用方法:
-
public E next()
:返回迭代中的下一个元素 -
public boolean hasNext()
:如果迭代器还有元素,返回true
而Collection集合中提供了获取迭代器的方法:
public Iterator iterator()
:获取集合对应的迭代器,用来遍历集合的元素。
public class IteratorDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(5);
list.add(3);
list.add(2);
list.add(4);
list.add(1);
// 获取迭代器Iterator
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
二.集合工具类Collections
注意这里的是Collections,比起集合Collection多了一个字母s,是一个集合工具类,提供了一些方法方便对集合进行操作。
常用的方法如下:
-
public static <T> boolean addAll(Collection<T> c, T... elements)
:将所有指定的元素添加到指定的集合中。 -
public static void shuffle(List<?> list)
:随机打乱集合顺序 -
public static <T> void sort(List<T> list)
:将集合中的元素按默认排序规则排序(升序) -
public static <T> void sort(List<T> list, Comparator<? super T> c)
:将集合中的元素按照指定规则进行排序
public class CollectionsDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
// 以前添加元素方式
// list.add(1);
// list.add(2);
// list.add(3);
// list.add(4);
// list.add(5);
// 使用Collections添加元素到list
Collections.addAll(list, 1,2,3,4,5);
System.out.println(list); // 输出:[1, 2, 3, 4, 5]
// 随机打乱集合元素顺序
Collections.shuffle(list);
System.out.println(list); // 输出:[1, 3, 4, 5, 2]
// 使用默认的排序规则排列list
Collections.sort(list);
System.out.println(list); // 输出:[1, 2, 3, 4, 5]
}
}
对于另一个排序方法:sort(List<T> list, Comparator<? super T> c)
,允许我们实现Comparator接口来自定义排序规则。
在java中提供了两种比较的实现方式:
java.langComparable
接口实现
如果一个类实现了Comparable,则意味着这个类支持排序,则可以通过Collections.sort或者Arrays.sort进行排序。
Comparable接口内部只有一个方法public int compareTo(T o),能够让实现Comparable接口的类对象进行比较,具体的比较规则是:
e1.compareTo(e2) > 0 则 e1 > e2
e1.compareTo(e2) = 0 则 e1 = e2
e1.compareTo(e2) < 0 则 e1 < e2
排列顺序其实主要是看-1,-1决定其是否要调整顺序: if(o1.compareTo(o2) < 0 ){ return ?; } //这里o1表示位于前面的字符,o2表示后面的字符 //上面的条件是,o1比o2小,这个时候,我们需要需要调整它们的顺序 //如果你想升序,那么o1比o2小就是我想要的;所以返回-1,类比成false;表示我不想调整顺序 //如果你想降序,那么o1比o2小不是我想要的;所以返回1,类比成true;表示我想调整顺序
记忆:
如果return e1 - e2; 默认为升序排序
如果return e2 - e1; 默认为降序排序
比如在类中实现Comparable接口,实现compareTo()方法:
@Override
public int compareTo(Person person) {
return this.age - person.age; // 升序
}
java.util.Comparator
接口实现
Comparator是比较器接口,可以将Comparator传递给sort方法,从而控制排序,也可以为那些没有实现排序的对象提供排序。
Comparator接口提供了一个比较方法:public int compare(T o1, T o2)
:比较两个参数的顺序
两个对象比较的结果有三种:大于,等于,小于,对于compare函数,是根据返回值来比较的。
记忆方式和比较方式和Comparable一样,可以看上面。
如果return o1 - o2; 默认为升序排序
如果return o2 - o1; 默认为降序排序
- 两者的区别
Comparable是自然排序,由实体类实现
Comparator是定制排序,无法修改实体类的实现时,直接在调用方创建
两者都存在时,采用Comparator的规则进行比较排序。
可以看出,Comparable相当于是内部的比较器,而Comparator则相当于是外部的比较器。 - 排序的练习
需求:对自定义类,存储到List集合中完成相关排序操作。
先实现自定义类:
package com.zzy.www.ListDemo;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Person person) {
return this.age - person.age; // 升序
}
}
如果想要集合的元素进行排序,那么Person必须要实现Comparable接口,才可排序,因此需要给Person类添加实现接口Comparable。
编写一个测试类:
public class Test {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<>();
// 添加元素
list.add(new Person("张三", 38));
list.add(new Person("李四", 25));
list.add(new Person("王五",20));
list.add(new Person("赵六", 18));
// 按年龄升序排序
Collections.sort(list);
// 遍历
for (Person p : list) {
System.out.println(p);
}
// 输出内容:
/*
Person{name='赵六', age=18}
Person{name='王五', age=20}
Person{name='李四', age=25}
Person{name='张三', age=38}
*/
}
}
以上的实现方式,对于存储Person对象的集合排序就只能用升序的方式排列了,如果想要使用其他规则去排序,显然改变Person中compareTo方法并不是一个好的方式,这是就可以使用Collections.sort方法实现Comparator接口,自己定义排序规则。
修改测试类:
public class Test {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<>();
// 添加元素
list.add(new Person("张三", 38));
list.add(new Person("李四", 25));
list.add(new Person("王五",20));
list.add(new Person("赵六", 18));
// 按年龄升序排序
// Collections.sort(list);
// 按年龄降序排序
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person person, Person t1) {
return t1.getAge() - person.getAge();
}
});
// 遍历
for (Person p : list) {
System.out.println(p);
}
/*输出:
Person{name='张三', age=38}
Person{name='李四', age=25}
Person{name='王五', age=20}
Person{name='赵六', age=18}*/
}
}
除了升序降序,如果还想要其他排序规则,都可以通过Collections.sort去定义,比如如下:
先按年龄降序排序,如果年龄一致,则按照姓名的首字母升序排序。
public class Test {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<>();
// 添加元素
list.add(new Person("zhangsan", 38));
list.add(new Person("lisi", 38));
list.add(new Person("wangwu",20));
list.add(new Person("zhaoliu", 18));
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person person, Person t1) {
int ret = person.getAge() - t1.getAge();
if (ret == 0) {
ret = person.getName().charAt(0) - t1.getName().charAt(0);
}
return ret;
}
});
// 遍历
for (Person p : list) {
System.out.println(p);
}
/*输出:
Person{name='zhaoliu', age=18}
Person{name='wangwu', age=20}
Person{name='lisi', age=38}
Person{name='zhangsan', age=38}*/
}
}