1.推薦使用subList處理局部列表
需求:一個列表100個元素,現(xiàn)在要刪除索引位置為20-30的元素,如果使用循環(huán),代碼如下:
public static void main(String[] arg){
//初始化一個固定長度不可變列表
List<Integer> initData = Collections.nCopies(100,0);
//轉(zhuǎn)化為可變列表
List<Integer> list = new ArrayList<Integer>(initData);
//遍歷
for(int i=0;i < list.seze)();i++){
if(i>=20 && i <30){
list.remove(i);
}
}
}
其實我們可以使用subList來處理
public static void main(String[] arg){
//初始化一個固定長度不可變列表
List<Integer> initData = Collections.nCopies(100,0);
//轉(zhuǎn)化為可變列表
List<Integer> list = new ArrayList<Integer>(initData);
list.subList(20,30).clear();
}
subList返回的是原始列表的一個試圖,輸出這個視圖中的所有元素最終會反映到原始列表
2.生成子列表后不要再操作原列表
public static void main(String[] arg){
List<Integer> srcList = new ArrayList<>();
srcList.add("a");
srcList.add("b");
srcList.add("c");
List<Integer> subList = srcList.subList(0,2);
//操作原列表
srcList.add("D");
System.out.println("原列表長度:"+srcList.size());
System.out.println("子列表長度:"+subList.size());
}
運行在subList.size()處報錯
- 原列表變化后,subList取出的這子列表不會生成新的列表,詳細可查看subList的源碼(原因出現(xiàn)在構(gòu)造參數(shù)的修改計數(shù)器上)
- 可以通過
list = Collection.unmodiflagList(list)設(shè)置原列表為只讀狀態(tài),避免subList后對原列表的更改 - 如果subList生成的試圖有多個,那么子列表也不可以修改
3.使用Comparator進行排序
在Java中要想給數(shù)據(jù)排序有兩種實現(xiàn)方式,一種是實現(xiàn)Comparable接口,一種是實現(xiàn)Comparator接口,這兩種有什么區(qū)別呢?
public class Employee implements Comparable<Employee>{
private int id;
private String name;
private Postion position;
public Employee(int _id,String _name,Position _position){
this.id = _id;
this.name= _name;
this.position = _position;
}
//省略getter,setter
//根據(jù)id進行排序
@Override
public int compareTo(Employee o){
return new CompareToBuilder().append(id,o.id).toComparison();
}
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this);
}
}
public enum Position(){
Boss,Manager,Staff
}
排序
List<Empoyee> list = new ArrayList<>();
//添加元素省略
//按照id排序
Collection.sort(list);
那么我們?nèi)绻胍凑章毼籶osition進行排序,那該怎么辦?Collection.sort有一個重載的方法Collection.sort(List<T> list,Comparator<? super T> c),代碼如下:
class PositionComparator implements Comparator<Employee>{
@Override
public int compare(Employee o1,Employee o2){
return o1.getPosition().compareTo(o2.getPosition());
}
}
那么倒序排列是否也要重寫排序器?不用
- 直接使用Collection.reverse(List<?> list)
- 通過Collection.sort<list,Collections.reverseOrder(new PositionComparator)>
那么如果職位相同再按照id排序該怎么處理:
public int compareTo(Employee o){
return new CompareToBuilder
.append(position,o.position).toComparison()
.append(id,o.id).toComparison();
}
4.不推薦使用binarySearch對列表進行檢索
Collections.binarySearch:使用二分搜索法收縮指定列表以獲取指定對象,其功能與indexOf是相同的。但是使用binarySearch需要注意:
- binarySearch使用前必須對列表進行排序,這是二分法的首要條件
- 對列表排序會打破有規(guī)則的業(yè)務(wù)數(shù)據(jù),慎用
- binarySearch在性能上相比indexOf是最好的選擇
5.集合中的元素必須做到compareTo與equals同步
public class city implements Comparable<city>{
private int code;
private String name;
public Employee(int _code,String _name){
this.id = _id;
this.name= _name;
}
//省略getter,setter
//根據(jù)name進行排序
@Override
public int compareTo(Employee o){
return new CompareToBuilder().append(name,o.name).toComparison();
}
@Override
public boolean equals(Object obj){
if(onj == null){
return false;
}
if(obj == this){
return true;
}
if(obj.getClass() != getClass()){
return false;
}
City city = (City) obj;
//根據(jù)code判斷是否相等
return new EqualsBuilder().append(code,city.code).isEquals();
}
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this);
}
}
public static void main(String[] arg){
List<Integer> cities = new ArrayList<>();
cities.add(new City("021","上海"));
cities.add(new City("021","滬"));
//排序
Collections.sort(cities);
//查找對象
City city = new City("021","滬");
List<Integer> subList = srcList.subList(0,2);
//indexOf取得索引值
int index1 = cities.indexOf(city);
//binarySearch取得索引值
int index2 = Collections.binarySearch(cities.city);
System.out.println("indexOf取得索引值:"+ index1);// 0
System.out.println("binarySearch取得索引值index2);// 1
}
為什么結(jié)果不一樣呢?indexOf是使用equals判斷的,binarySearch是通過compareTo方法,而這兩個方法并不一致,所以結(jié)果不一樣
6.集合運算使用更優(yōu)雅的方式
- 并集:list1.addAll(list2)
- 交集:list1.retainAll(list2)
- 差集:list1.removeAll(list2)
- 無重復(fù)并集:list2.removeAll(list1);list1.addAll(list2)