java.util.Collections是集合的工具类,提供了很多静态方法来操作集合,其中sort方法可以对List集合进行自然排序。
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.sort(list,(i1,i2)->i2-i1);//lambda表达式重写排序方式
Collections.shuffle(list);//乱序
集合排序自定义类型元素
List<Point> list = new ArrayList<>();
list.add(new Point(1,2));
list.add(new Point(15,8));
list.add(new Point(9,7));
list.add(new Point(5,3));
list.add(new Point(4,6));
System.out.println(list);
/*
编译不通过。原因:集合元素没有实现接口Comparable。只有实现了该接口的类
才可以进行比较(实现接口后就必须重写方法compareTo()用于定义两个元素间的
比较大小规则)。
该操作对我们的代码具有侵入性,不建议这样做。
侵入性:当我们调用一个功能时,其要求我们为其修改其他额外的代码,这就是侵入性
它不利于程序后期的维护与扩展,应当尽量避免。
*/
//Collections.sort(list); 编译不通过
//匿名内部类写法
// Comparator<Point> c = new Comparator<Point>() {
// @Override
// public int compare(Point o1, Point o2) {//compare:比较
// int len1 = o1.getX()*o1.getX()+o1.getY()* o1.getY();
// int len2 = o2.getX()*o2.getX()+o2.getY()* o2.getY();
// return len1-len2;
// 当返回值>0 o1>o2 返回值<0 o1<o2 返回值=0 o1=o2
// }
// };
// Collections.sort(list,c);
//没有侵入性的写法
// Collections.sort(list,new Comparator<Point>() {
// @Override
// public int compare(Point o1, Point o2) {//compare:比较
// 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()
);//最后的简化
当元素本身实现了Comparable接口并定义了比较规则,但是按照该规则排序后不满足我们的排序 需求时,我们也可以自定义比较规则。
List<String> list = new ArrayList<>();
list.add("苍老师");
list.add("传奇");
list.add("小泽老师");
System.out.println(list);//[苍老师, 传奇, 小泽老师]
//使用重载的sort方法,定义一个比较器,按照字数多少排序。
Collections.sort(list,(s1,s2)->s2.length()-s1.length());
System.out.println(list);//[小泽老师, 苍老师, 传奇]
增强型for循环
语法:for(元素类型 变量名 :集合或数组){
...
}
泛型,也称参数化类型,允许在使用一个类时去指定该类中某个属性的类型或方法返回值的类型或方法参数的类型,使得我们使用这个类时更方便更灵活。泛型常用在集合中,用于指定集合中的元素类型。
String[] array = {"one","two","three","four","five"};
for(String e : array){
System.out.println(e);
}
//编译器会改为普通循环遍历。
/*
Collection<E>定义时,指定了一个泛型E。我们在实际使用集合时可以指定
E的实际类型。这样一来,编译器会检查我们使用泛型时的类型是否匹配。
例如集合的方法:
boolean add(E e)
编译器会检查我们调用add方法向集合中添加元素时,元素的类型是否为E指定的
类型,不符合编译不通过。
*/
Collection<String> c = new ArrayList<>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
//c.add(123); 不符合E在这里的实际类型String,因此编译不通过。
//新循环遍历集合会改回成迭代器遍历
for(String s : c){
System.out.println(s);
}
//迭代器也支持泛型,指定时要与其遍历的集合指定的泛型一致。
Iterator<String> e = c.iterator();
while(e.hasNext()){
String str = e.next();
System.out.println(str);
}
数组转集合,Arrays提供的方法asList可以将数组转为一个List集合,可以进行替换元素,但不能改变数组长度,否则会出现java.lang.UnsupportedOperationException:不支持的异常操作
/*
所有的集合都支持一个参数为Collection的构造器,作用是在创建当前集合的同时
包含给定集合中的所有元素
*/
List<String> list2 = new ArrayList<>(list);
System.out.println("list2:"+list2);//list2:[one, six, three, four, five]
list2.add("seven");
System.out.println("list2:"+list2);//list2:[one, six, three, four, five, seven]
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);
/*
toArray方法传入的数组长度实际没有长度要求,就功能而言如果给定的数组长度>=
集合的size时,就是用该数组(将集合元素存入到数组中)然后将其返回。
如果指定的数组长度不足时会根据该数组类型自行创建一个与集合size一致的数组
并返回。
*/
String[] array = c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(array));