目录
重载的Collections.sort(List list,Comparator c)方法
java.util.Collection 接口 :
是所有集合的顶级接口,规定了所有集合具有的功能。
- 其中两个常见的子接口 ( 常用实现类 ) :
java.util.ArrayList:内部使用数组实现,查询性能更好.
java.util.LinkedList:内部使用链表实现,首尾增删元素性能更好.
List集合:
java.util.list接口
List接口继承自Collection。
List集合的特点:可以存放重复元素且有序。
List提供了一套通过下标操作元素的方法。
常用实现类:
java.util.ArrayList:内部使用数组实现,查询性能更好。
java.util.LinkedList:内部使用链表实现,首尾增删性能更好。
PS:在性能没有苛刻要求时,通常使用ArrayList
List 集合常见方法:
1、get ( ) 与 set ( )
- 根据下标获取指定元素
- E . get (int index)
- 数组、集合名 . get( 位 置 )
将给定元素设置到指定位置,并返回被替换的元素
E . set ( int index , E e )
集合、数组名 . set ( 位 置 , 替换内容)
- 补充:
- 反转集合:将集合、数组内所有元素反转
- Collections . reverse ( 集合 ) ;
package collection;
import java.util.ArrayList;
import java.util.List;
/**
* List集合
* List是Collection下面常见的一类集合。
* java.util.List接口是所有List的接口,它继承自Collection。
* 常见的实现类:
* java.util.ArrayList:内部由数组实现,查询性能更好。
* java.util.LinkedList:内部由链表实现,增删性能更好。
*
* List集合的特点是:可以存放重复元素,并且有序。其提供了一套可以通过下标
* 操作元素的方法。
*/
public class ListDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// List<String> list = new LinkedList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
list.add("five");
/*
E get(int index)
获取指定下标对应的元素
*/
//获取第三个元素
String e = list.get(2);
System.out.println(e);
for(int i=0;i<list.size();i++){
e = list.get(i);
System.out.println(e);
}
/*
E set(int index,E e)
将给定元素设置到指定位置,返回值为该位置原有的元素。
替换元素操作
*/
//[one,six,three,four,five]
String old = list.set(1,"six");
System.out.println(list);
System.out.println("被替换的元素是:"+old);
}
}
2、重载的 add ( ) 和 remove ( )
将给定元素插入到指定位置
void . add ( int index , E e )
集合、数组名 . add ( 位 置 ,替换元素 )
删除并返回指定位置上的元素
E . remove ( int index )
集合、数组名 . remove ( 位 置 )
package collection;
import java.util.ArrayList;
import java.util.List;
/**
* List集合提供了一对重载的add,remove方法
*/
public class ListDemo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
list.add("five");
System.out.println(list);
/*
void add(int index,E e)
将给定元素插入到指定位置
*/
//[one,two,six,three,four,five]
list.add(2,"six");
System.out.println(list);
/*
E remove(int index)
删除并返回指定位置上的元素
*/
//[one,six,three,four,five]
String e = list.remove(1);
System.out.println(list);
System.out.println("被删除的元素:"+e);
}
}
3、List集合支持获取子集操作 subList()方法:
获取当前集合中指定范围内的子集。两个参数为开始与结束的下标(含头不含尾)
List . subList ( int start , int end )
集合、数组名 . subList(开始下标 ,结束下标)
对子集的操作就是对原集合对应位置的操作!
补充若要删除集合中某部分元素:
E . subList ( int start , int end ) . clear ( ) ;
集合、数组名 . subList(开始下标 ,结束下标) . clear ( ) ;
package collection;
import java.util.ArrayList;
import java.util.List;
/**
* List subList(int start,int end)
* 获取当前集合中指定范围内的子集。两个参数为开始与结束的下标(含头不含尾)
*/
public class ListDemo3 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++){
list.add(i);
}
System.out.println(list);
//获取3-7这部分
List<Integer> subList = list.subList(3,8);
System.out.println(subList);
//将子集每个元素扩大10倍
for(int i=0;i<subList.size();i++){
subList.set(i,subList.get(i) * 10);
}
//[30,40,50,60,70]
System.out.println(subList);
/*
对子集元素的操作就是对原集合对应元素的操作
*/
System.out.println(list);
//删除list集合中的2-8
list.subList(2,9).clear();
System.out.println(list);
}
}
集合与数组的转换
1 )集合转换为数组
- Collection提供了一个方法 : toArray , 可以将当前集合转换为一个数组
- 集合的toArray方法要求传入一个数组,
- 1)如果该数组可用( 长度 > = 集合 size )
- 则 将集合元素全部存入该数组后再将该数组返回
- 2)如果数组不可用( 长度 < 集合 size )
- 则 会自动创建一个与集合等长的数组,并将元素存入该数组后将其返回
package apiday04;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
/**
* 集合转换为数组
*/
public class CollectionToArrayDemo {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
System.out.println("集合:"+c); //集合:[one, two, three, four, five]
//Object[] array = c.toArray();
// .toArray() 返回的类型只能是Object类型,很坑,一般情况我们不用这个
//因为在1.5时,一同出了一个新的方法
/**
* 集合的toArray方法要求传入一个数组,
* 1)如果该数组可用(长度>=集合size)则
* 将集合元素全部存入该数组后再将该数组返回
* 2)如果数组不可用(长度<集合size)则
* 会自动创建一个与集合等长的数组,并将元素存入该数组后将其返回
*/
// String[] array = c.toArray(new String[c.size()]); //将数组的长度添加到其中c.size()
// String[] array = c.toArray(new String[10]); //新数组长度为10 //数组:[one, two, three, four, five, null, null, null, null, null]
String[] array = c.toArray(new String[0]); //创建新数组长度<旧数组,会不用当前0长度自动更改为与旧集合的长度相同的数组,返回给你
System.out.println("数组:"+ Arrays.toString(array)); //数组:[one, two, three, four, five]
}
}
2)数组转换为 List 集合 (只能转 List)
- 数组的工具类Arrays提供了一个静态方法:
- asList ( ) 语法:Aarrays . asList ( )
- 使用 Arrays 的 asList 方法可以将数组转换为一个 List 集合
- 之所以不能转换为其他类型集合,比如 Set,是因为 Set 集合不能存档重复元素
- 语法: List <String> list = Arrays.asList ( array ) ;
- List <泛型> 变量名 = Arrays.asList ( 数组名 ) ;
- 由于数组是定长的,因此对该集合进行增删元素的操作是不支持的,
- 会抛出异常: java.lang.UnsupportedOperationException
- 不支持 操作 异常
- 所有集合都提供了一个参数为Collection的构造器,
- 目的是在创建当前集合的同时,包含给定集合中的所有元素
package apiday04;
import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 数组转换集合
* 注意: 只能转 List
*/
public class ArrayToListDemo {
public static void main(String[] args) {
String[] array = {"one","two","three","four","five"}; //数组[one, two, three, four, five]
System.out.println("数组"+Arrays.toString(array));
/**
* 使用Arrays的asList方法可以将数组转换为一个List集合
* 之所以不能转换为其他类型集合比如Set,是因为Set集合不能存档重复元素
*/
List<String> list = Arrays.asList(array);
System.out.println("List:"+list); //List:[one, two, three, four, five]
/**
* 从数组转换而来的List集合是不能 增删 元素的,会报异常:
* java.lang.UnsupportedOperationException
* 不支持 操作 异常
*/
// list.add("six"); //报错,因为不能增删
// System.out.println("List:"+list);
// List<String> list2 = new ArrayList<>(); //我们此处重写Arrays,来实现增删操作
// list2.addAll(list);
/**
* 若希望对集合进行增删操作,则需要自行创建一个集合,并将数组转换而来的集合元素导入后 方可操作
*
* 语法*/
List<String> list2 = new ArrayList<>(list);
System.out.println("list2:"+list2);//list2:[one, two, three, four, five]
list2.add("six"); //增加 six
System.out.println("list2:"+list2);//list2:[one, two, three, four, five, six]
/**
* 所有集合都提供了一个参数为Collection的构造器,
* 目的是在创建当前集合的同时,包含给定集合中的所有元素
*/
}
}
集合的排序
- java.util.Collections类
- Collections 是集合的工具类 , 里面定义了很多静态方法用于操作集合
- Collections . sort ( List list ) 方法
- 可以对 List 集合进行自然排序 ( 从小到大 )
- 排序自定义类型元素 (通常情况下编译不通过)
- 原因:
- Collections . sort ( List list ) 该方法
- 要求集合中的元素类型必须实现接口:Comparable ,
- Comparable :该接口中有一个抽象方法 compareTo ,
- compare To :这个方法用来定义元素之间比较大小的规则
- 所以只有实现了该接口的元素,
- 才能利用这个方法比较出大小进而实现排序操作.
- P S :实际开发中,我们并不会让我们自己定义的类 ( 如果该类作为集合元素使用 )
- 去实现 Comparable 接口 , 因为这对我们的程序有侵入性 .
- 侵入性 : 当我们调用某个API功能时 , 其要求我们为其修改其他额外的代码 ,
- 这个现象就 是 侵入性 .
- 侵入性越强的 API 越不利于程序的后期可维护性 . 应当尽量避免 !
- 此时我们应用到 匿名内部类 来解决
package collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 排序自定义类型元素
*/
public class SortListDemo2 {
public static void main(String[] args) {
List<Point> list = new ArrayList<>();
list.add(new Point(1,2));
list.add(new Point(97,88));
list.add(new Point(7,6));
list.add(new Point(9,9));
list.add(new Point(5,4));
list.add(new Point(2,3));
System.out.println(list);
/*
编译不通过的原因:
Collections.sort(List list)该方法要求集合中的元素类型必须实现接口:
Comparable,该接口中有一个抽象方法compareTo,这个方法用来定义元素之间比较
大小的规则.所以只有实现了该接口的元素才能利用这个方法比较出大小进而实现排序
操作.
*/
Collections.sort(list);//编译不通过 compare比较 comparable可以比较的
System.out.println(list);
}
}
重载的 Collections.sort ( List list , Comparator c ) 方法
- 重载的 sort 方法会根据我们传入的比较将 list 集合元素两两比较 ,
- 然后根据大小关系 进行 从小到大排序
//为Point定义一个比较规则: 点到原点长的大
//为哪个类定义比较器 泛型就指定哪个类
Comparator<Point> c = new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) { //compare:比较
//计算o1点到原点的距离(此处应用到 勾股定理:a*a + b*b = c*c)
// (忽略开方,因为是求谁更长,不是求精确长度)
int len1 = o1.getX()* o1.getX() + o1.getY()* o1.getY();
int len2 = o2.getX()* o2.getX() + o2.getY()* o2.getY();//o2 同理
return len1-len2;
/*
* 返回值表示o1与o2的大小关系有三种情况:
* o1>o2: 应当返回一个 >0 的数
* o1<o2: 应当返回一个 <0 的数
* o1=o2: 应当返回 0
*/
}
};
Collections.sort(list,c);
Collections.sort(list, new Comparator<Point>() {
@Override
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;
}
});
System.out.println(list);
最终没有侵入性的写法:
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);
排序字符串
- java中提供的类 , 如 : String , 包装类都实现了 Comparable 接口 ,
- 但有时候这些比较规则不能满足我们的排序需求时 ,
- 同样可以临时提供一种比较规则来进行排序 .
//按照字符多少排序
Collections.sort(list,(o1,o2)->o2.length()-o1.length());