前提:
list中的元素是自定义对象,如何根据对象的元素进行排序呢?
比如List<Student>students 是一个list,每个元素都是Student对象,Student对象中有成员变量name,age,等,
那么我想根据age来排序,如何实现呢?
1,使用Comparator 接口
Student类 结构如下:(省略getter,setter方法)
public class Student {
/***
* 姓名
*/
private String name;
private int age;
private String address;
/***
* 考试得分
*/
private int score;
//省略getter,setter方法
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score
+ "]";
}
}
测试方法:
@Test
public void test_ListComparator(){
List<Student>students=new ArrayList<Student>();
Student stu=null;
stu=new Student();
stu.setName("whuang");
stu.setAge(12);
stu.setScore(80);
students.add(stu);
stu=new Student();
stu.setName("rong");
stu.setAge(11);
stu.setScore(90);
students.add(stu);
stu=new Student();
stu.setName("zhu");
stu.setAge(15);
stu.setScore(100);
students.add(stu);
Collections.sort(students,new SystemHWUtil. ListComparator(true,"age"));
System.out.println(students);
}
运行结果:
[Student [name=rong, age=11, score=90], Student [name=whuang, age=12, score=80], Student [name=zhu, age=15, score=100]]
核心类:
public static class ListComparator implements Comparator{
/***
* 是否转化为Int之后再比较
*/
private boolean isConvertInteger;
/***
* 对哪个列进行排序
*/
private String comparedProperty;
public ListComparator(boolean isConvertInteger,String comparedProperty) {
super();
this.isConvertInteger = isConvertInteger;
this.comparedProperty=comparedProperty;
}
public int compare(Object o1, Object o2) {
if(null!=o1&&null!=o2)
{
try {
Object obj1=ReflectHWUtils.getObjectValue(o1, comparedProperty);
Object obj2=ReflectHWUtils.getObjectValue(o2, comparedProperty);
if(isConvertInteger){
int num1;
int num2;
if(obj1 instanceof Integer){
num1=(Integer)obj1;
num2=(Integer)obj2;
}else{
num1=Integer.parseInt(obj1.toString());
num2=Integer.parseInt(obj2.toString());
}
if(num1>num2){
return 1;
}else if(num1<num2){
return -1;
}else{
return 0;
}
}else{
return obj1.toString().compareTo(obj2.toString());
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return 0/*等于*/;
}
}
2,可以指定是升序还是降序
实例:
@Test
public void test_ListComparator(){
List<Student>students=new ArrayList<Student>();
Student stu=null;
stu=new Student();
stu.setName("whuang");
stu.setAge(12);
stu.setScore(80);
students.add(stu);
stu=new Student();
stu.setName("rong");
stu.setAge(11);
stu.setScore(90);
students.add(stu);
stu=new Student();
stu.setName("zhu");
stu.setAge(15);
stu.setScore(100);
students.add(stu);
SortList<Student> sortList = new SortList<Student>();
sortList.Sort(students, "getAge", "asc");
System.out.println(students);
}
注意:sortList.Sort 的第二个参数是方法名,不是成员变量名.
核心代码
package com.common.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortList<E> {
public void Sort(List<E> list, final String method, final String sort) {
Collections.sort(list, new Comparator() {
public int compare(Object a, Object b) {
int ret = 0;
try {
Method m1 = ((E) a).getClass().getMethod(method, null);
Method m2 = ((E) b).getClass().getMethod(method, null);
if (sort != null && "desc".equals(sort))// 倒序
ret = m2.invoke(((E) b), null).toString()
.compareTo(m1.invoke(((E) a), null).toString());
else
// 正序
ret = m1.invoke(((E) a), null).toString()
.compareTo(m2.invoke(((E) b), null).toString());
} catch (NoSuchMethodException ne) {
System.out.println(ne);
} catch (IllegalAccessException ie) {
System.out.println(ie);
} catch (InvocationTargetException it) {
System.out.println(it);
}
return ret;
}
});
}
}
通用排序工具类
1,实际应用:
List<OrderInfoBean> orderInfoBeans = commitOrderDto.getValue();
SortList<OrderInfoBean> sortList = new SortList<OrderInfoBean>();
sortList.Sort(orderInfoBeans, "getCreateTime", "desc");
2,工具类sortList源码
package com.gov.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/***
* 用户排序
* @author huangwei
* 2015年7月1日
* @param <E>
*/
public class SortList<E> {
public void Sort(List<E> list, final String method, final String sort) {
Collections.sort(list, new Comparator() {
public int compare(Object a, Object b) {
int ret = 0;
try {
Method m1 = ((E) a).getClass().getMethod(method, null);
Method m2 = ((E) b).getClass().getMethod(method, null);
if (sort != null && "desc".equals(sort))// 倒序
ret = m2.invoke(((E) b), null).toString()
.compareTo(m1.invoke(((E) a), null).toString());
else
// 正序
ret = m1.invoke(((E) a), null).toString()
.compareTo(m2.invoke(((E) b), null).toString());
} catch (NoSuchMethodException ne) {
System.out.println(ne);
} catch (IllegalAccessException ie) {
System.out.println(ie);
} catch (InvocationTargetException it) {
System.out.println(it);
}
return ret;
}
});
}
}
另外一种排序方式
实例:
List<CommonDictionary>list= DictionaryParam.getList("ptype");
Collections.sort(list,new SystemHWUtil. ListComparator(true,"value"));
model.addAttribute("commonDictionaries", list);
说明:list的类型是ArrayList;
按照list中的元素(CommonDictionary对象)的成员变量value进行排序
SystemHWUtil. ListComparator的源代码:
public static class ListComparator implements Comparator{
/***
* 是否转化为Int之后再比较
*/
private boolean isConvertInteger;
/***
* 对哪个列进行排序
*/
private String comparedProperty;
public ListComparator(boolean isConvertInteger,String comparedProperty) {
super();
this.isConvertInteger = isConvertInteger;
this.comparedProperty=comparedProperty;
}
public int compare(Object o1, Object o2) {
if(null!=o1&&null!=o2)
{
try {
Object obj1=ReflectHWUtils.getObjectValue(o1, comparedProperty);
Object obj2=ReflectHWUtils.getObjectValue(o2, comparedProperty);
if(isConvertInteger){
int num1;
int num2;
if(obj1 instanceof Integer){
num1=(Integer)obj1;
num2=(Integer)obj2;
}else{
num1=Integer.parseInt(obj1.toString());
num2=Integer.parseInt(obj2.toString());
}
if(num1>num2){
return 1;
}else if(num1<num2){
return -1;
}else{
return 0;
}
}else{
return obj1.toString().compareTo(obj2.toString());
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return 0/*等于*/;
}
}
附录:
public static class ArrayListComparator implements Comparator{
/***
* 排序的依据
*/
private String titles[];
/***
* 对哪个列进行排序
*/
private String comparedProperty;
public ArrayListComparator(String[] titles,String comparedProperty) {
super();
this.titles = titles;
this.comparedProperty=comparedProperty;
}
public int compare(Object o1, Object o2) {
if(null!=o1&&null!=o2)
{
try {
if(SystemHWUtil.indexOfArr(titles,(String)ReflectHWUtils.getObjectValue(o1, comparedProperty) ) >
SystemHWUtil.indexOfArr(titles,(String)ReflectHWUtils.getObjectValue(o2, comparedProperty))){
return 1/*大于*/;
}else {
return -1/*小于*/;
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return 0/*等于*/;
}
}
JAVA8-让代码更优雅之List排序
先定义一个实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Human {
private String name;
private int age;
}
下面的操作都基于这个类来进行操作。这里面使用了Lombok类库,它用注解的方式实现了基本的get和set等方法,让代码看起来更加的优雅。
JAVA8之前的List排序操作
在Java8之前,对集合排序只能创建一个匿名内部类
new Comparator<Human>() {
@Override
public int compare(Human h1, Human h2) {
return h1.getName().compareTo(h2.getName());
}
}
下面是简单的对Humans进行排序(按名称正序)
@Test
public void testSortByName_with_plain_java() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
Collections.sort(humans, new Comparator<Human>() {
public int compare(Human h1, Human h2) {
return h1.getName().compareTo(h2.getName());
}
});
Assert.assertThat(humans.get(0), equalTo(new Human("li", 25)));
}
使用Lambda的List排序
使用JAVA8函数式方式的比较器
(Human h1, Human h2) -> h1.getName().compareTo(h2.getName())
下面是使用JAVA8函数式的比较的例子
@Test
public void testSortByName_with_lambda() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
humans.sort((Human h1, Human h2) -> h1.getName().compareTo(h2.getName()));
Assert.assertThat("tomy", equalTo(humans.get(1).getName()));
}
没有类型定义的排序
对于上面的表达式还可以进行简化,JAVA编译器可以根据上下文推测出排序的类型:
(h1, h2) -> h1.getName().compareTo(h2.getName())
简化后的比较器是这样的:
@Test
public void testSortByNameSimplify_with_lambda() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
humans.sort((h1, h2) -> h1.getName().compareTo(h2.getName()));
Assert.assertThat("tomy", equalTo(humans.get(1).getName()));
}
使用静态方法引用
JAVA8还可以提供使用Lambda表达式的静态类型引用,我们在Human类增加一个静态比较方法,如下:
public static int compareByNameThenAge(Human h1, Human h2) {
if (h1.getName().equals(h2.getName())) {
return Integer.compare(h1.getAge(), h2.getAge());
}
return h1.getName().compareTo(h2.getName());
}
然后就可以在humans.sort使用这个引用
@Test
public void testSort_with_givenMethodDefinition() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
humans.sort(Human::compareByNameThenAge);
Assert.assertThat("tomy", is(equalTo(humans.get(1).getName())));
}
使用单独的Comparator
JAVA8已经提供了很多方便的比较器供我们使用,比如Comparator.comparing方法,所以可以使用Comparator.comparing方法来实现根据Human的name进行比较的操作:
@Test
public void testSort_with_givenInstanceMethod() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
Collections.sort(humans, Comparator.comparing(Human::getName));
Assert.assertThat("tomy", equalTo(humans.get(1).getName()));
}
反序
JDK8中也提供了一个支持倒序排序的方法方便我们更快的进行倒序
@Test
public void testSort_with_comparatorReverse() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
Comparator<Human> comparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
humans.sort(comparator.reversed());
Assert.assertThat("tomy", equalTo(humans.get(0).getName()));
}
使用多个条件进行排序
Lambda提供了更复杂的表达式,还可以先对name排序再根据age进行排序:
@Test
public void testSort_with_multipleComparator() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
Comparator<Human> comparator = (h1, h2) -> {
if (h1.getName().equals(h2.getName())) {
return Integer.compare(h1.getAge(), h2.getAge());
}
return h1.getName().compareTo(h2.getName());
};
humans.sort(comparator.reversed());
Assert.assertThat("tomy", equalTo(humans.get(0).getName()));
}
使用多个条件进行排序-组合的方式
Comparator对这种组合的排序有更优雅实现,从JDK8开始,我们可以使用链式操作进行复合操作来构建更复杂的逻辑:
@Test
public void testSort_with_multipleComparator_composition() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("tomy", 25)
);
humans.sort(Comparator.comparing(Human::getName).thenComparing(Human::getAge));
Assert.assertThat(humans.get(0), equalTo(new Human("tomy", 22)));
}
总结
JDK8真的是一个非常值得我们学习的版本,它提供了Lambda表达式,带来了函数式编程的理念,让JAVA代码更优雅。
浅谈SortedList方法使用 出处:http://teachcourse.cn/1870.html
一.摘要
SortedList继承Object,属于android.utils包工具类,与java.utils包下的List、ArrayList木有什么关系(继承或实现)。一个排序的list实现类保证items选项的顺序,list顺序、items值改变发送提醒通知,比如:RecyclerView.Adapter。比较items之间的位置关系使用compare(Object,Object)方法,该方法采用的是二分查找获取items。如果items排序的标准发生改变,当编辑时未避免数据的不一致需要确保回调合适的方法。SortedList.Callback元素用于控制items的顺序和通知改变。
二.内部类
SortedList嵌套两个内部类SortedList.BatchedCallback、SortedList.Callback,前者用于批量通知被SortedList调度的事件的回调实现,后者控制SortedList的行为。
三.构造方法
SortedList(Class kclass,Callback callback)
创建一个指定类型T的SortedList对象。
SortedList(Class kclass,Callback callback,int initialCapacity)
创建一个指定类型T的SortedList对象,同时指定长度initialCapacity。
四.SortedList方法解析
查看SortedList文档后发现,SortedList可以指定位置更新数据或批量更新,删除指定的item值,数据的操作包括:比较,插入,删除,移动,改变,分别回调对应的方法:compare(),onInserted(),onRemoved(),onMoved(),onChanged(),相比ArrayList,LinkedList,SortedList操作更加方便。创建一个实体SortedListBean,使用SorteList存储实体对象,然后根据id排序,简单的用法:
- /**
- * Created by TeachCourse.cn on 2016/6/25 10:31.
- */
- public class SorteListBean implements Serializable {
- private String id;
- private String name;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public SorteListBean(String id, String name) {
- this.id = id;
- this.name = name;
- }
- }
SortedList在用法上和ArrayList或LinkedList一样,功能上比它们多一些,代码比较多,只粘贴部分
- /**
- * 初始化数据
- */
- private void initData() {
- mSortedList = new SortedList<SorteListBean>(SorteListBean.class, mBatchedCallback);
- mSortedList.add(new SorteListBean("2011110924", "zhaolin"));
- mSortedList.add(new SorteListBean("2011110925", "bocheng"));
- mSortedList.add(new SorteListBean("2011110926", "binge"));
- mSortedList.add(new SorteListBean("2011110927", "boge"));
- mSortedList.add(new SorteListBean("2011110928", "wangzai"));
- }
- /**重写内部类
- *初始化回调内部类
- */
- private SortedList.Callback<SorteListBean> mCallback = new SortedList.Callback<SorteListBean>() {
- @Override
- public int compare(SorteListBean o1, SorteListBean o2) {
- String id1 = o1.getName();
- String id2 = o2.getName();
- return id1.compareTo(id2);
- }
- @Override
- public void onInserted(int position, int count) {
- }
- @Override
- public void onRemoved(int position, int count) {
- }
- @Override
- public void onMoved(int fromPosition, int toPosition) {
- }
- @Override
- public void onChanged(int position, int count) {
- }
- @Override
- public boolean areContentsTheSame(SorteListBean oldItem, SorteListBean newItem) {
- return false;
- }
- @Override
- public boolean areItemsTheSame(SorteListBean item1, SorteListBean item2) {
- return false;
- }
- };
- /**
- * 批量回调
- */
- protected SortedList.BatchedCallback<SorteListBean> mBatchedCallback = new SortedList.BatchedCallback<SorteListBean>(mCallback);
1.add(T item),添加给出的item到list中
- mSortedList.add(new SortedListBean("2011110929","teachcourse.cn"));
2.addAll(T... items),一次性添加多个items到list中
- mSortedList.addAll(new SortedListBean("2011110929","teachcourse.cn"),new SorteListBean("2011110924", "zhaolin"));
3.addAll(Collection items),添加给出的items到指定的list中,不修改输入
- Collection<SorteListBean> collection=new ArrayList<>();
- collection.add(new SorteListBean("2011110924", "zhaolin"));
- collection.add(new SorteListBean("2011110925", "bocheng"));
- collection.add(new SorteListBean("2011110927", "boge"));
- collection.add(new SorteListBean("2011110928", "wangzai"));
- mSortedList.addAll(collection);
关于Collection的使用讲解可以查看《Collection接口解析》
4.addAll(T[] items,boolean mayModifyInput),添加给出的items到指定的list中,mayModifyInput为true允许修改输入
- SorteListBean[] sorteListBeen=new SorteListBean[]{new SorteListBean("2011110924", "zhaolin"),new SorteListBean("2011110925", "bocheng")};
- mSortedList.addAll(sorteListBeen,true);
5.beginBatchedUpdates(),批量处理适配器更新操作发生在调用当前方法和调用endBatchedUpdates()之间
- mSortedList.beginBatchedUpdates();
- try {
- mSortedList.add(new SorteListBean("2011110924", "zhaolin"))
- mSortedList.add(new SorteListBean("2011110925", "bocheng"))
- mSortedList.remove(new SorteListBean("2011110927", "boge"))
- ...
- } finally {
- mSortedList.endBatchedUpdates();
- }
6.clear(),从SortedList中删除所有的items
- mSortedList.clear();
6.endBatchedUpdates(),结束更新事务,回调处理事件,和beginBatchedUpdates()一起使用
7.get(int index),返回指定索引的item
- SortedListBean bean=mSortedList.get(0);
8.indexOf(T item),返回指定item对应的索引位置
- int index=mSortedList.indexOf(mSortedListBean);
9.recalculatePositionOfItemAt(int index),重新计算指定索引的item位置,当没有触发onChanged(int,int)回调方法时
- final int position = mSortedList.indexOf(item);
- item.incrementPriority(); // assume items are sorted by priority
- mSortedList.recalculatePositionOfItemAt(position);
10.remove(T item),删除指定的item,然后调用onRemoved()方法
- mSortedList.remove(mSortedListBean);
11.removeItemAt(int index),删除指定索引的item,然后调用onRemoved()方法
- mSortedList.removeItemAt(0);
12.updateItemsAt(int index,T item),更新指定索引的item,然后调用onChanged(int,int)方法,onMoved(int,int)方法
- mSortedList.updateItemAt(0,new SorteListBean("2011110927", "boge"));