在 Java 中以 mm/dd/yy 格式根据最新日期对数组列表进行排序

Sort array list based on most recent date in mm/dd/yy format in Java

提问人:codrp 提问时间:11/1/2023 最后编辑:Arpita Shrivastavacodrp 更新时间:11/2/2023 访问量:86

问:

我正在尝试根据销售日期对数组进行排序,格式为 MM/dd/yy。目前,排序后我在数组的第一个对象中得到了错误的日期。排序数组中第一个对象中的预期日期为 。01/12/24

法典

import java.util.*;
import java.util.stream.*;

class Car{
    String name;
    String sold;
    public Car(String name, String sold){
        this.name = name;
        this.sold = sold;
    }
    public String getSold(){
        return this.sold;
    }
}

public class MyClass {
    public static void main(String args[]) {
    
      List<Car> list = new ArrayList<Car>();
      list.add(new Car("bmw", "01/12/24"));
      list.add(new Car("jeep", "02/12/23"));
      list.add(new Car("audi", "12/12/23"));
      
      List<Car> sortedList = list.stream().sorted(Comparator.comparing(Car::getSold).reversed()).collect(Collectors.toList());
      
      System.out.println("sorted "+ sortedList.get(0).sold);
    }
}

我使用 JDoodle 创建了一个工作示例。谁能帮忙?

java 数组列表

评论

5赞 maio290 11/1/2023
您可能应该使用实际日期对象,例如 LocalDate。它们实现了 Comparable 接口,因此应该可以很好地与流及其方法一起使用。
1赞 Luatic 11/1/2023
MM/dd/yy不适合进行词典比较。

答:

1赞 gdomo 11/1/2023 #1

您必须将销售日期解析为日期并按此进行比较:

    DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("MM/dd/yy");
    List<Car> sortedList = list.stream()
            .sorted(Comparator.<Car, LocalDate>comparing(car -> LocalDate.parse(car.getSold(), dayFormatter)).reversed())
            .toList();

评论

0赞 VGR 11/2/2023
不需要该部件。<Car, LocalDate>
2赞 Viorel Mirea 11/1/2023 #2

排序问题是因为您尝试排序的日期是一个字符串。您需要将其转换为 LocalDate。 我添加了 LocalDate 类型的 soldDate 变量,该变量将包含转换为 LocalDate 的字符串日期的值。您将使用它进行排序。
更新了代码以捕获错误并按照建议从类中删除字符串。

    import java.util.*;
    import java.time.*;
    import java.text.*;
    import java.util.stream.*;
    
    class Car{
        String name;
        LocalDate soldDate;
        public Car(String name, String sold){
            this.name = name;
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yy");
            try {
                this.soldDate = LocalDate.parse(sold, formatter);
            } catch (DateTimeParseException e) {
                System.out.println("Invalid date format: " + sold);
            }
        }
    
        public LocalDate getSold(){
            return this.soldDate;
        }
    }
    
    public class MyClass {
        public static void main(String args[]) {
        
          List<Car> list = new ArrayList<Car>();
          list.add(new Car("bmw", "01/12/24"));
          list.add(new Car("jeep", "02/12/23"));
          list.add(new Car("audi", "12/12/23"));
          
          List<Car> sortedList = list.stream().sorted(Comparator.comparing(Car::getSoldDate).reversed()).collect(Collectors.toList());
          
          if(!sortedList.isEmpty()) {
              System.out.println("sorted " + sortedList.get(0).sold);
          } else {
              System.out.println("No cars with valid date format found");
          }
   }
}

评论

0赞 MadProgrammer 11/1/2023
仅供参考:将抛出您目前没有处理的问题LocalDate.parseDateTimeParseException
2赞 Basil Bourque 11/1/2023 #3

tl;博士

定义具有适当数据类型的类。

record CarSale ( String name , LocalDate whenSold ) {}

然后构建一个 ,并调用 .ListList#sort

new ArrayList<>(
    List.of(
        new Car( "bmw", LocalDate.parse( "2024-01-12" ) ) ,
        new Car( "jeep", LocalDate.parse( "2023-02-12" ) ) ,
        new Car( "audi", LocalDate.parse( "2023-12-12" ) )
    )
)
.sort( CarSales :: whenSold )

如果类的主要目的是透明地传达不可变数据,请定义为记录

使用日期时间类表示日期时间值。对于仅日期值,请使用 java.time.LocalDate

record CarSale ( String name , LocalDate whenSold ) {}

调用此类的代码应根据需要解析文本输入。(清理格式不佳的输入文本不是工作。请参阅关注点分离CarSaleCarSale

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uu" ) ;

String input = "01/12/24" ;
LocalDate ld = LocalDate.parse( input , f ) ;

传递给我们类的隐式构造函数。CarSale

CarSale cs = new CarSale( nameInput , ld ) ;

将这些对象收集到可修改对象中,例如 .CarSaleListArrayList

List< CarSale > carSales = new ArrayList <>() ;
carSales.add( cs ) ;

最后,对列表进行排序。将方法引用传递给我们填充的对象的 getter 方法。该类的对象知道如何对自身进行排序。LocalDateLocalDate

carSales.sort( CarSales :: whenSold ) ;

提示:请告知数据发布者如何仅使用标准 ISO 8601 格式来交换日期时间值。