網頁

2019/7/3

Java 8 使用Stream.sorted()對List物件進行排序範例

本篇為使用Java 8 Stream.sorted()方法來對List中的元素進行排序。

下面範例使用Steam.sorted對裝有多個自訂的TF2Class物件進行排序。sorted()Comparator物件為參數,通常是直接呼叫Comparator.comparing()來產生。

Comparator.comparing()接收一個Functional Interface 的Function<T,R>參數。

package com.abc.demo;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) throws Exception {
        
        List<TF2Class> classes = List.of(
            new TF2Class("Scout",   125, 1.33),
            new TF2Class("Soldier", 200, 0.80),
            new TF2Class("Pyro",    175, 1.00),
            new TF2Class("Demoman", 175, 0.93),
            new TF2Class("Heavy",   300, 0.77),
            new TF2Class("Engineer",125, 1.00),
            new TF2Class("Medic",   150, 1.07),
            new TF2Class("Sniper",  125, 1.00),
            new TF2Class("Spy",     125, 1.07)
        );
        

        System.out.println("依生命值(health)升冪排序 - 匿名函式類別");
        classes.stream().sorted(Comparator.comparing(new Function<TF2Class, Integer>() { 
                                                      // Function<? super T,? extends U>的型別第一個為List元素的實例,第二個型別為要比較的型別
            @Override
            public Integer apply(TF2Class t) {
                return t.getHealth();
            }
            
        })).collect(Collectors.toCollection(ArrayList::new))
            .forEach(System.out::println);
        
        System.out.println("\n-------------------------------");
        
        
        System.out.println("依生命值(health)升冪排序 - lambda");
        classes.stream().sorted(Comparator.comparing((t) -> {
            return t.getName();
        })).collect(Collectors.toCollection(ArrayList::new))
            .forEach(System.out::println);
        
        System.out.println("\n-------------------------------");
        
        
        System.out.println("依生命值(health)升冪排序 - method reference");
        classes.stream().sorted(Comparator.comparing(TF2Class::getHealth))
            .collect(Collectors.toCollection(ArrayList::new)) // by 肉豬
            .forEach(System.out::println);
        
        System.out.println("\n-------------------------------");
        
        
        System.out.println("依生命值(health)降冪排序");
        classes.stream().sorted(Comparator.comparing(TF2Class::getHealth).reversed())
            .collect(Collectors.toCollection(ArrayList::new))
            .forEach(System.out::println);
        
        System.out.println("\n-------------------------------");
        
        
        System.out.println("先依生命值(health)升冪排序,再依速度值(speed)升冪排序");
        classes.stream().sorted(
                    Comparator.comparing(TF2Class::getHealth)
                            .thenComparing(TF2Class::getSpeed)
                )
            .collect(Collectors.toCollection(ArrayList::new))
            .forEach(System.out::println);
        
        System.out.println("\n-------------------------------");
       
        
        System.out.println("依名稱(name)自然排序");
        classes.stream().sorted()
            .collect(Collectors.toCollection(ArrayList::new))
            .forEach(System.out::println);
        
        System.out.println("\n-------------------------------");
        
        
        System.out.println("依名稱(name)自然排序");
        classes.stream().sorted(new Comparator<TF2Class>() {

            @Override
            public int compare(TF2Class t1, TF2Class t2) {
                return t1.getName().compareTo(t2.getName());
            }

            
        }).collect(Collectors.toCollection(ArrayList::new))
            .forEach(System.out::println);
        System.out.println("\n-------------------------------");
        
        
        System.out.println("依名稱(name)自然排序");
        classes.stream().sorted(Comparator.comparing(new Function<TF2Class, String>() {

            @Override
            public String apply(TF2Class t) {
                return t.getName();
            }
            
        })).collect(Collectors.toCollection(ArrayList::new))
            .forEach(System.out::println);
        
    }
}

class TF2Class implements Comparable<TF2Class> {
    
    private String name;
    private int health;
    private double speed;
    
    public TF2Class(String name, int health, double speed) {
        super();
        this.name = name;
        this.health = health;
        this.speed = speed;
    }

    @Override
    public String toString () {
        return new StringBuilder(name).append(",")
                    .append(health).append(",")
                    .append(speed).toString();
    }

    @Override
    public int compareTo(TF2Class t) {
        return this.name.compareTo(t.getName());
    }
    
    // getters and setters...
    
}

印出結果如下

依生命值(health)升冪排序 - 匿名函式類別
Scout,125,1.33
Engineer,125,1.0
Sniper,125,1.0
Spy,125,1.07
Medic,150,1.07
Pyro,175,1.0
Demoman,175,0.93
Soldier,200,0.8
Heavy,300,0.77

-------------------------------
依生命值(health)升冪排序 - lambda
Demoman,175,0.93
Engineer,125,1.0
Heavy,300,0.77
Medic,150,1.07
Pyro,175,1.0
Scout,125,1.33
Sniper,125,1.0
Soldier,200,0.8
Spy,125,1.07

-------------------------------
依生命值(health)升冪排序 - method reference
Scout,125,1.33
Engineer,125,1.0
Sniper,125,1.0
Spy,125,1.07
Medic,150,1.07
Pyro,175,1.0
Demoman,175,0.93
Soldier,200,0.8
Heavy,300,0.77

-------------------------------
依生命值(health)降冪排序
Heavy,300,0.77
Soldier,200,0.8
Pyro,175,1.0
Demoman,175,0.93
Medic,150,1.07
Scout,125,1.33
Engineer,125,1.0
Sniper,125,1.0
Spy,125,1.07

-------------------------------
先依生命值(health)升冪排序,再依速度值(speed)升冪排序
Engineer,125,1.0
Sniper,125,1.0
Spy,125,1.07
Scout,125,1.33
Medic,150,1.07
Demoman,175,0.93
Pyro,175,1.0
Soldier,200,0.8
Heavy,300,0.77

-------------------------------
依名稱(name)自然排序
Demoman,175,0.93
Engineer,125,1.0
Heavy,300,0.77
Medic,150,1.07
Pyro,175,1.0
Scout,125,1.33
Sniper,125,1.0
Soldier,200,0.8
Spy,125,1.07

-------------------------------
依名稱(name)自然排序
Demoman,175,0.93
Engineer,125,1.0
Heavy,300,0.77
Medic,150,1.07
Pyro,175,1.0
Scout,125,1.33
Sniper,125,1.0
Soldier,200,0.8
Spy,125,1.07

-------------------------------
依名稱(name)自然排序
Demoman,175,0.93
Engineer,125,1.0
Heavy,300,0.77
Medic,150,1.07
Pyro,175,1.0
Scout,125,1.33
Sniper,125,1.0
Soldier,200,0.8
Spy,125,1.07


參考:

1 則留言: