java 对list进行排序

前提:

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排序,简单的用法:

  1. /** 
  2.  * Created by TeachCourse.cn on 2016/6/25 10:31. 
  3.  */  
  4. public class SorteListBean implements Serializable {  
  5.     private  String id;  
  6.     private String name;  
  7.   
  8.     public String getId() {  
  9.         return id;  
  10.     }  
  11.   
  12.     public void setId(String id) {  
  13.         this.id = id;  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24.     public SorteListBean(String id, String name) {  
  25.         this.id = id;  
  26.         this.name = name;  
  27.     }  
  28. }  

SortedList在用法上和ArrayList或LinkedList一样,功能上比它们多一些,代码比较多,只粘贴部分

  1. /** 
  2.  * 初始化数据 
  3.  */  
  4. private void initData() {  
  5.         mSortedList = new SortedList<SorteListBean>(SorteListBean.class, mBatchedCallback);  
  6.         mSortedList.add(new SorteListBean("2011110924", "zhaolin"));  
  7.         mSortedList.add(new SorteListBean("2011110925", "bocheng"));  
  8.         mSortedList.add(new SorteListBean("2011110926", "binge"));  
  9.         mSortedList.add(new SorteListBean("2011110927", "boge"));  
  10.         mSortedList.add(new SorteListBean("2011110928", "wangzai"));  
  11. }  
  12.   
  13. /**重写内部类 
  14.  *初始化回调内部类 
  15.  */  
  16. private SortedList.Callback<SorteListBean> mCallback = new SortedList.Callback<SorteListBean>() {  
  17.   
  18.   
  19.         @Override  
  20.         public int compare(SorteListBean o1, SorteListBean o2) {  
  21.             String id1 = o1.getName();  
  22.             String id2 = o2.getName();  
  23.             return id1.compareTo(id2);  
  24.         }  
  25.   
  26.         @Override  
  27.         public void onInserted(int position, int count) {  
  28.   
  29.         }  
  30.   
  31.         @Override  
  32.         public void onRemoved(int position, int count) {  
  33.   
  34.         }  
  35.   
  36.         @Override  
  37.         public void onMoved(int fromPosition, int toPosition) {  
  38.   
  39.         }  
  40.   
  41.         @Override  
  42.         public void onChanged(int position, int count) {  
  43.   
  44.         }  
  45.   
  46.         @Override  
  47.         public boolean areContentsTheSame(SorteListBean oldItem, SorteListBean newItem) {  
  48.             return false;  
  49.         }  
  50.   
  51.         @Override  
  52.         public boolean areItemsTheSame(SorteListBean item1, SorteListBean item2) {  
  53.             return false;  
  54.         }  
  55.     };  
  56. /** 
  57.  * 批量回调 
  58.  */  
  59. protected SortedList.BatchedCallback<SorteListBean> mBatchedCallback = new SortedList.BatchedCallback<SorteListBean>(mCallback);  

1.add(T item),添加给出的item到list中

  1. mSortedList.add(new SortedListBean("2011110929","teachcourse.cn"));  

2.addAll(T... items),一次性添加多个items到list中

  1. mSortedList.addAll(new SortedListBean("2011110929","teachcourse.cn"),new SorteListBean("2011110924", "zhaolin"));  

3.addAll(Collection items),添加给出的items到指定的list中,不修改输入

  1. Collection<SorteListBean> collection=new ArrayList<>();  
  2.     collection.add(new SorteListBean("2011110924", "zhaolin"));  
  3.     collection.add(new SorteListBean("2011110925", "bocheng"));  
  4.     collection.add(new SorteListBean("2011110927", "boge"));  
  5.     collection.add(new SorteListBean("2011110928", "wangzai"));  
  6.     mSortedList.addAll(collection);  

关于Collection的使用讲解可以查看《Collection接口解析

4.addAll(T[] items,boolean mayModifyInput),添加给出的items到指定的list中,mayModifyInput为true允许修改输入

  1. SorteListBean[] sorteListBeen=new SorteListBean[]{new SorteListBean("2011110924", "zhaolin"),new SorteListBean("2011110925", "bocheng")};  
  2.           mSortedList.addAll(sorteListBeen,true);  

5.beginBatchedUpdates(),批量处理适配器更新操作发生在调用当前方法和调用endBatchedUpdates()之间

  1. mSortedList.beginBatchedUpdates();  
  2.      try {  
  3.          mSortedList.add(new SorteListBean("2011110924", "zhaolin"))  
  4.          mSortedList.add(new SorteListBean("2011110925", "bocheng"))  
  5.          mSortedList.remove(new SorteListBean("2011110927", "boge"))  
  6.          ...  
  7.      } finally {  
  8.          mSortedList.endBatchedUpdates();  
  9.      }  

6.clear(),从SortedList中删除所有的items

  1. mSortedList.clear();  

6.endBatchedUpdates(),结束更新事务,回调处理事件,和beginBatchedUpdates()一起使用

7.get(int index),返回指定索引的item

  1. SortedListBean bean=mSortedList.get(0);  

8.indexOf(T item),返回指定item对应的索引位置

  1. int index=mSortedList.indexOf(mSortedListBean);  

9.recalculatePositionOfItemAt(int index),重新计算指定索引的item位置,当没有触发onChanged(int,int)回调方法时

  1. final int position = mSortedList.indexOf(item);  
  2.      item.incrementPriority(); // assume items are sorted by priority  
  3.      mSortedList.recalculatePositionOfItemAt(position);  

10.remove(T item),删除指定的item,然后调用onRemoved()方法

  1. mSortedList.remove(mSortedListBean);  

11.removeItemAt(int index),删除指定索引的item,然后调用onRemoved()方法

  1. mSortedList.removeItemAt(0);  

12.updateItemsAt(int index,T item),更新指定索引的item,然后调用onChanged(int,int)方法,onMoved(int,int)方法

  1. mSortedList.updateItemAt(0,new SorteListBean("2011110927", "boge"));  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值