【问题标题】:Sorting a list with stream.sorted() in Java在 Java 中使用 stream.sorted() 对列表进行排序
【发布时间】:2017-03-23 21:54:51
【问题描述】:

我对从流中排序列表感兴趣。这是我正在使用的代码:

list.stream()
    .sorted((o1, o2)->o1.getItem().getValue().compareTo(o2.getItem().getValue()))
    .collect(Collectors.toList());

我错过了什么吗?该列表未在之后排序。

它应该根据具有最低值的项目对列表进行排序。

for (int i = 0; i < list.size(); i++)
{
   System.out.println("list " + (i+1));
   print(list, i);
}

以及打印方式:

public static void print(List<List> list, int i)
{
    System.out.println(list.get(i).getItem().getValue());
}

【问题讨论】:

    标签: java list sorting java-stream


    【解决方案1】:

    这不像Collections.sort() 对参数引用进行排序。在这种情况下,您只需要收集一个排序的流,最终将其分配给另一个变量:

    List result = list.stream().sorted((o1, o2)->o1.getItem().getValue().
                                       compareTo(o2.getItem().getValue())).
                                       collect(Collectors.toList());
    

    你刚刚错过了分配结果

    【讨论】:

      【解决方案2】:

      改用list.sort

      list.sort((o1, o2) -> o1.getItem().getValue().compareTo(o2.getItem().getValue()));
      

      并使用Comparator.comparing 使其更简洁:

      list.sort(Comparator.comparing(o -> o.getItem().getValue()));
      

      在其中任何一个之后,list 本身将被排序。

      你的问题是 list.stream.sorted 返回排序后的数据,它没有按照你的预期排序。

      【讨论】:

      • list.sort(Comparator.comparing(o -&gt; o.getItem().getValue())); 对我来说是新的。太好了!
      【解决方案3】:

      Java 8 提供了不同的实用 API 方法来帮助我们更好地对流进行排序。

      如果您的列表是整数列表(或 Double、Long、String 等),那么您可以简单地使用 java 提供的默认比较器对列表进行排序。

      List<Integer> integerList = Arrays.asList(1, 4, 3, 4, 5);
      

      动态创建比较器:

      integerList.stream().sorted((i1, i2) -> i1.compareTo(i2)).forEach(System.out::println);
      

      当没有参数传递给 sorted() 时,使用 java 8 提供的默认比较器:

      integerList.stream().sorted().forEach(System.out::println); //Natural order
      

      如果要对同一个列表进行倒序排序:

       integerList.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println); // Reverse Order
      

      如果您的列表是用户定义对象的列表,那么:

      List<Person> personList = Arrays.asList(new Person(1000, "First", 25, 30000),
              new Person(2000, "Second", 30, 45000),
              new Person(3000, "Third", 35, 25000));
      

      动态创建比较器:

      personList.stream().sorted((p1, p2) -> ((Long)p1.getPersonId()).compareTo(p2.getPersonId()))
              .forEach(person -> System.out.println(person.getName()));
      

      使用 Comparator.comparingLong() 方法(我们也有 compareDouble()、compareInt() 方法):

      personList.stream().sorted(Comparator.comparingLong(Person::getPersonId)).forEach(person -> System.out.println(person.getName()));
      

      使用 Comparator.comparing() 方法(基于提供的 getter 方法进行比较的通用方法):

      personList.stream().sorted(Comparator.comparing(Person::getPersonId)).forEach(person -> System.out.println(person.getName()));
      

      我们也可以使用 thenComparing() 方法进行链接:

      personList.stream().sorted(Comparator.comparing(Person::getPersonId).thenComparing(Person::getAge)).forEach(person -> System.out.println(person.getName())); //Sorting by person id and then by age.
      

      人物类

      public class Person {
          private long personId;
          private String name;
          private int age;
          private double salary;
      
          public long getPersonId() {
              return personId;
          }
      
          public void setPersonId(long personId) {
              this.personId = personId;
          }
      
          public Person(long personId, String name, int age, double salary) {
              this.personId = personId;
              this.name = name;
              this.age = age;
      
              this.salary = salary;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          public double getSalary() {
              return salary;
          }
      
          public void setSalary(double salary) {
              this.salary = salary;
          }
      }
      

      【讨论】:

      • 我觉得这个答案对于这个问题来说太详细了,但根本没有解决这个问题。考虑在自我回答的问答中使用此答案。
      • 我也觉得这是最好最正确的答案。使用Comparator.comparing* 是更好、更面向 JDK8 的方法
      【解决方案4】:

      它似乎工作正常:

      List<BigDecimal> list = Arrays.asList(new BigDecimal("24.455"), new BigDecimal("23.455"), new BigDecimal("28.455"), new BigDecimal("20.455"));
      System.out.println("Unsorted list: " + list);
      final List<BigDecimal> sortedList = list.stream().sorted((o1, o2) -> o1.compareTo(o2)).collect(Collectors.toList());
      System.out.println("Sorted list: " + sortedList);
      

      输入/输出示例

      Unsorted list: [24.455, 23.455, 28.455, 20.455]
      Sorted list: [20.455, 23.455, 24.455, 28.455]
      

      您确定您没有验证列表而不是 sortedList [在上面的示例中],即您将 stream() 的结果存储在一个新的 List 对象中并验证该对象?

      【讨论】:

      • 完美运行!
      【解决方案5】:

      使用 streamAPI 对整数进行排序

      arr.stream()
      .sorted((item1,item2)-> Integer.compare(item1.price, item2.price))
      .forEach(item-> item.show());
      //asc
      System.out.println("--------------------");
      //desc
      arr.stream()
      .sorted((item1,item2)-> item1.price<item2.price?1:-1)
      .forEach(item->item.show());
      

      【讨论】:

        【解决方案6】:

        这是一个简单的例子:

        List<String> citiesName = Arrays.asList( "Delhi","Mumbai","Chennai","Banglore","Kolkata");
        System.out.println("Cities : "+citiesName);
        List<String> sortedByName = citiesName.stream()
                        .sorted((s1,s2)->s2.compareTo(s1))
                                .collect(Collectors.toList());
        System.out.println("Sorted by Name : "+ sortedByName);
        

        您的 IDE 可能没有获取 jdk 1.8 或更高版本来编译代码。

        为 Your_Project 设置 Java 版本 1.8 > 属性 > 项目方面 > Java 版本 1.8

        【讨论】:

          【解决方案7】:
          Collection<Map<Item, Integer>> itemCollection = basket.values();
          Iterator<Map<Item, Integer>> itemIterator =   itemCollection.stream().sorted(new TestComparator()).collect(Collectors.toList()).iterator();
          
          
          
          package com.ie.util;
          
          import com.ie.item.Item;
          
          import java.util.Comparator;
          import java.util.Iterator;
          import java.util.Map;
          import java.util.Set;
          
          public class TestComparator implements Comparator<Map<Item, Integer>> {
          
          // comparator is used to sort the Items based on the price
          
          
              @Override
              public int compare(Map<Item, Integer> o1, Map<Item, Integer> o2) {
          
          
                //  System.out.println("*** compare method will be called *****");
          
          
                  Item item1 = null;
                  Item item2 = null;
          
          
                  Set<Item> itemSet1 = o1.keySet();
                  Iterator<Item> itemIterator1 = itemSet1.iterator();
                  if(itemIterator1.hasNext()){
                     item1 =   itemIterator1.next();
                  }
          
                  Set<Item> itemSet2 = o2.keySet();
                  Iterator<Item> itemIterator2 = itemSet2.iterator();
                  if(itemIterator2.hasNext()){
                      item2 =   itemIterator2.next();
                  }
          
          
                  return -item1.getPrice().compareTo(item2.getPrice());
          
          
              }
          }
          

          **** 这有助于对嵌套的地图对象(如 Map)进行排序> 这里我根据 Item 对象价格进行排序。

          【讨论】:

            【解决方案8】:

            这可能对最终在这里搜索如何按字母顺序排序列表的人有所帮助。

            import lombok.Getter;
            import lombok.Setter;
            import lombok.ToString;
            
            import java.util.ArrayList;
            import java.util.Comparator;
            import java.util.List;
            
            public class SortService {
                public static void main(String[] args) {
                    List<TestData> test = new ArrayList<>();
                    test.add(prepareTestData("Asmin",1));
                    test.add(prepareTestData("saurav",4));
                    test.add(prepareTestData("asmin",2));
                    test.add(prepareTestData("Saurav",3));
            
                    test.forEach(data-> System.out.println(data));
                    /** Output
                     *  TestData(name=Asmin, id=1)
                     *  TestData(name=saurav, id=4)
                     *  TestData(name=asmin, id=2)
                     *  TestData(name=Saurav, id=3)
                     */
            
                    test.sort(Comparator.comparing(TestData::getName,String::compareToIgnoreCase));
                    test.forEach(data-> System.out.println(data));
                    /**Sorted Output
                     * TestData(name=Asmin, id=1)
                     * TestData(name=asmin, id=2)
                     * TestData(name=saurav, id=4)
                     * TestData(name=Saurav, id=3)
                     */
                }
                private static TestData prepareTestData(String name, int id){
                    TestData testData= new TestData();
                    testData.setId(id);
                    testData.setName(name);
                    return testData;
                }
            }
            
            @Getter
            @Setter
            @ToString
            class TestData{
                private String name;
                private int id;
            }
            

            【讨论】:

            • 看起来您没有利用任何与流相关的代码。
            猜你喜欢
            • 2018-09-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-09
            • 1970-01-01
            • 2020-12-23
            • 2018-10-20
            相关资源
            最近更新 更多