关于java list的排序问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于java list的排序问题相关的知识,希望对你有一定的参考价值。

list里的元素都是map,我要根据map里的code字段进行排序
list输出的内容例子:
CodeList=[errorMessage=, returnCode=0, returnData= found in vlan 1367, code=MACConfig, advice=testaaaa1,
errorMessage=, returnCode=0, returnData=, code=checkPortState, advice=testdddd,
errorMessage=, returnCode=0, returnData=, code=checkVLAN, advice=ccccc]
里面三个MAP元素,比如我code为checkPortState 我要放到第一,code为checkVLAN放第二,总之可以根据code自己自定义位置。

楼上你可以用用linkedhashmap来存放对象 这样就可以按照你放的顺序输出了。

TreeMap的顺序是自然顺序(如整数从小到大),也可以指定比较函数。但不是插入的顺序。

LinkedHashMap吧。它内部有一个链表,保持插入的顺序。迭代的时候,也是按照插入顺序迭代,而且迭代比HashMap快。
参考技术A 自己实现一个比较器:
Collections.sort(CodeList,new Comparator<Map<String,String>>()
@Override
public int compare(Map<String,String> o1, Map<String,String> o2)
String code_1 = o1.get("code");
String code_2 = o2.get("code");
return code_1.compareTo(code_2);

);
希望能帮上忙...追问

先谢谢!
这样的话是按照String类型,a b c d 这样进行排序,那如果当code=checkPortState我必须放到第一位置,怎么处理?

追答

你可以给用户一个List,如CustomList,让他们自定义这些值的排序,比如,第一位置的就放在0,第二位的放在1.....然后,CodeList的排序就根据这个自定义数组来,比如CodeList的第一个Map,你取出它的code,然后拿到这个code在CustomList里的Index,就可以知道应该是排在哪个位置了,然后创建一个临时List,如TmpList,TmpList.add(index,code)...多次循环,就可以得到一个排好序的TmpList了....

本回答被提问者和网友采纳

Java8实战list分组过滤统计排序等常用操作

引言

在前面,写过java8实战系列文章,文章的内容都是基于《Java8 in Action》一书学习总结的。
这段时间在项目中很多地方都用到了,但很多时候都需要现查一下该怎么写,本篇博客就来总结一下关于List的一些常用的流操作。

基础代码

学生实体代码如下:
@Data
public class Student implements Serializable 
    /**
     * 编号
     */
    private Integer id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 班级
     */
    private String className;
    /**
     * 所在省
     */
    private String province;
    /**
     * 学号
     */
    private Integer stuNo;
    /**
     * 入学成绩
     */
    private Double score;

    public Student(Integer id, String name, Integer age, String className, String province, Integer stuNo, Double score) 
        this.id = id;
        this.name = name;
        this.age = age;
        this.className = className;
        this.province = province;
        this.stuNo = stuNo;
        this.score = score;
    

学生list代码如下:
private List<Student> buildStudentList() 
    return Arrays.asList(new Student(1, "张扬", 18, "A", "北京", 45, 83.2),
                         new Student(2, "李丹", 22, "A", "天津", 15, 65.5),
                         new Student(3, "张丹", 22, "B", "山东", 44, 78.4),
                         new Student(4, "白天", 19, "B", "北京", 1, 63.7),
                         new Student(5, "王武", 20, "C", "湖南", 34, 78.3)
                        );

下面将通过对学生list的操作来展示如何使用java8中的stream来对list进行转换、分组、过滤、求和、排序等操作。

流的使用

1. Collectors.joining:list转换为指定字符分隔的字符串

/**
 * list转字符串,指定逗号字符分隔
 */
@Test
public void stuJoin() 
    List<Student> students = buildStudentList();
    //集合中的名字用逗号分隔
    String names = students.stream().map(Student::getName).collect(Collectors.joining(","));
    //结果:张扬,李丹,张丹,白天,王武
    System.out.println(names);

2. Collectors.toMap:list转换为map

/**
 * list转map
 * toMap 如果集合对象有重复的key,会报错Duplicate key ....
 * word1,word2的id都为1。
 * 可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
 */
@Test
public void stuMap() 
    List<Student> students = buildStudentList();
    Map<Integer, Student> studentMap = students.stream().collect(Collectors.toMap(Student::getId, s -> s, (s1, s2) -> s1));
    //结果:1=Student(id=1, name=张扬, age=18, className=A, province=北京, stuNo=45, score=83.2), 2=Student(id=2, name=李丹, age=22, className=A, province=天津, stuNo=15, score=65.5), 3=Student(id=3, name=张丹, age=22, className=B, province=山东, stuNo=44, score=78.4), 4=Student(id=4, name=白天, age=19, className=B, province=北京, stuNo=1, score=63.7), 5=Student(id=5, name=王武, age=20, className=C, province=湖南, stuNo=34, score=78.3)
    System.out.println(studentMap);

3. Collectors.groupingBy:分组

/**
 * 按对象指定属性分组
 */
@Test
public void stuGroup() 
    List<Student> students = buildStudentList();
    //按照班级进行分组
    Map<String, List<Student>> classMap = students.stream().collect(Collectors.groupingBy(Student::getClassName));
    //结果:A=[Student(id=1, name=张扬, age=18, className=A, province=北京, stuNo=45, score=83.2), Student(id=2, name=李丹, age=22, className=A, province=天津, stuNo=15, score=65.5)], B=[Student(id=3, name=张丹, age=22, className=B, province=山东, stuNo=44, score=78.4), Student(id=4, name=白天, age=19, className=B, province=北京, stuNo=1, score=63.7)], C=[Student(id=5, name=王武, age=20, className=C, province=湖南, stuNo=34, score=78.3)]
    System.out.println(classMap);

4. filter:过滤

/**
 * 过滤出某个值的集合
 */
@Test
public void stuFilter() 
    List<Student> students = buildStudentList();
    //筛选出省份为北京的学生
    List<Student> list = students.stream().filter(s -> s.getProvince().equals("北京")).collect(Collectors.toList());
    //结果:[Student(id=1, name=张扬, age=18, className=A, province=北京, stuNo=45, score=83.2), Student(id=4, name=白天, age=19, className=B, province=北京, stuNo=1, score=63.7)]
    System.out.println(list);

5. Collectors.summarizingDouble:统计

/**
 * 分组后统计数据(集合个数、分数求和、最小值、平均值、最大值)
 */
@Test
public void stuStatistics() 
    List<Student> students = buildStudentList();
    //按照班级进行分组
    Map<String, DoubleSummaryStatistics> classMap = students.stream().collect(Collectors.groupingBy(Student::getClassName, Collectors.summarizingDouble(Student::getScore)));
    //结果:A=DoubleSummaryStatisticscount=2, sum=148.700000, min=65.500000, average=74.350000, max=83.200000, B=DoubleSummaryStatisticscount=2, sum=142.100000, min=63.700000, average=71.050000, max=78.400000, C=DoubleSummaryStatisticscount=1, sum=78.300000, min=78.300000, average=78.300000, max=78.300000
    System.out.println(classMap);
    //分组后指定集合的总和:148.7
    System.out.println(classMap.get("A").getSum());
    //分组后指定集合的最大值:78.4
    System.out.println(classMap.get("B").getMax());
    //分组后指定集合的最小值:65.5
    System.out.println(classMap.get("A").getMin());
    //分组后指定集合的平均值:74.35
    System.out.println(classMap.get("A").getAverage());
    //分组后指定集合的个数:1
    System.out.println(classMap.get("C").getCount());

6. Collectors.toCollection:set去重

/**
 * 去重
 */
@Test
public void stuSet() 
    List<Student> students = buildStudentList();
    ArrayList<Student> list = students.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getProvince))), ArrayList::new));
    //结果:[Student(id=1, name=张扬, age=18, className=A, province=北京, stuNo=45, score=83.2), Student(id=2, name=李丹, age=22, className=A, province=天津, stuNo=15, score=65.5), Student(id=3, name=张丹, age=22, className=B, province=山东, stuNo=44, score=78.4), Student(id=5, name=王武, age=20, className=C, province=湖南, stuNo=34, score=78.3)]
    System.out.println(list);

7. max和min:最大值和最小值

/**
 * 最大值和最小值
 */
@Test
public void stuMaxMin() 
    List<Student> students = buildStudentList();
    //结果:Student(id=2, name=李丹, age=22, className=A, province=天津, stuNo=15, score=65.5)
    students.stream().max(Comparator.comparing(Student::getAge)).ifPresent(System.out::println);
    //结果:Student(id=1, name=张扬, age=18, className=A, province=北京, stuNo=45, score=83.2)
    students.stream().min(Comparator.comparing(Student::getAge)).ifPresent(System.out::println);

8. sorted:排序

/**
 * 排序
 */
@Test
public void stuSort() 
    List<Student> students = buildStudentList();
    //筛选B班的学生,并按年龄从小到大排序
    List<Student> list = students.stream().filter(s -> "B".equals(s.getClassName())).sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
    //结果:[Student(id=4, name=白天, age=19, className=B, province=北京, stuNo=1, score=63.7), Student(id=3, name=张丹, age=22, className=B, province=山东, stuNo=44, score=78.4)]
    System.out.println(list);
    //筛选B班的学生,并分数从高到低
    List<Student> listReverse = students.stream().filter(s -> "B".equals(s.getClassName())).sorted(Comparator.comparing(Student::getScore).reversed()).collect(Collectors.toList());
    //结果:[Student(id=3, name=张丹, age=22, className=B, province=山东, stuNo=44, score=78.4), Student(id=4, name=白天, age=19, className=B, province=北京, stuNo=1, score=63.7)]
    System.out.println(listReverse);

总结

下面是流的常用方法总结,可根据实际场景选择使用:

在实际项目中,真正体会到有时候复杂的需求,直接用流操作,能很容易实现,并且代码上简化了很多。
PS:又是一年1024,程序员(媛)们节日快乐!

以上是关于关于java list的排序问题的主要内容,如果未能解决你的问题,请参考以下文章

关于java list循环的问题

关于Java中Array.sort()排序原理,越详细越好!

关于linked list的java程序设计

java list<T> 根据两个字段排序

java list<T> 根据两个字段排序

java关于Map的排序性的一次使用,有序的Map