Java 对列表进行分类的最佳方法
我有一个订单对象Java 对列表进行分类的最佳方法,java,collections,Java,Collections,我有一个订单对象 public class Order{ private Date orderDate; //other fields + getters & setters } 和订单列表(List)。现在,我想根据相似的orderDate(此处相似的意思是同一年、同一月、同一天)对该订单列表进行分组,并生成如下地图: Map<Date, List<Order>> orderMap = new HashMap<>(); Map order
public class Order{
private Date orderDate;
//other fields + getters & setters
}
和订单列表(ListMap<Date, List<Order>> orderMap = new HashMap<>();
Map orderMap=newhashmap();
如何在Java8+中实现这一点
请注意,我们可能有相似的日期,但不同的时间戳,这意味着我们
想根据“年、月、日”来计算吗
您可以创建一个返回订单“相似性”的方法,例如:
公共类秩序{
私有日期orderDate;
//其他字段+getter和setter
公共字符串getStringDate(){
SimpleDataFormat dateFormat=新的SimpleDataFormat(“yyyy/MM/dd”);
return dateFormat.format(this.orderDate);
}
}
然后对其进行分组:
Map ordersWithSimilarOrderDate=orders.stream().collect(Collectors.groupingBy(Order::getStringDate));
您可以创建一个返回订单“相似性”的方法,例如:
公共类秩序{
私有日期orderDate;
//其他字段+getter和setter
公共字符串getStringDate(){
SimpleDataFormat dateFormat=新的SimpleDataFormat(“yyyy/MM/dd”);
return dateFormat.format(this.orderDate);
}
}
然后对其进行分组:
Map ordersWithSimilarOrderDate=orders.stream().collect(Collectors.groupingBy(Order::getStringDate));
由于Date
类已被弃用并保存实际日期和时间,您可以使用LocalDateTime
作为Order
类中的字段。然后,您可以根据取自LocalDateTime
的LocalDate
对订单进行分组:
List<Order> list = new LinkedList<>();
Map<LocalDate, List<Order>> collect = list.stream()
.collect(Collectors.groupingBy(order -> order.getOrderDate().toLocalDate()));
List List=newlinkedlist();
Map collect=list.stream()
.collect(Collectors.groupingBy(order->order.getOrderDate().toLocalDate());
保存没有时间的年、月和日。由于
Date
类已被弃用并保存实际日期和时间,您可以使用LocalDateTime
作为Order
类中的字段。然后,您可以根据取自LocalDateTime
的LocalDate
对订单进行分组:
List<Order> list = new LinkedList<>();
Map<LocalDate, List<Order>> collect = list.stream()
.collect(Collectors.groupingBy(order -> order.getOrderDate().toLocalDate()));
List List=newlinkedlist();
Map collect=list.stream()
.collect(Collectors.groupingBy(order->order.getOrderDate().toLocalDate());
可以无时间地保存年、月、日。我并不支持使用流做任何事情,但你可以做到 以一种艰难的转换方式
List orders=。。。你的名单。。。
Map orderMap=orders.stream().collect(收集器)groupingBy(订单->{
//从日期转换为即时
Instant dateInstant=order.getOrderDate().toInstant();
//将Instant转换为LocalDateTime并将其设置为一天的开始
LocalDateTime dateTime=dateInstant.atZone(ZoneId.systemDefault()).toLocalDate().atStartOfDay();
//将其转换回瞬间
Instant startOfDayInstant=dateTime.atZone(ZoneId.systemDefault()).toInstant();
//返回util日期
返回日期。起始日期(startOfDayInstant);
}));
这是在您需要util date的情况下。否则,我支持michalk的答案,我并不支持用流做任何事情,但你可以做到 以一种艰难的转换方式
List orders=。。。你的名单。。。
Map orderMap=orders.stream().collect(收集器)groupingBy(订单->{
//从日期转换为即时
Instant dateInstant=order.getOrderDate().toInstant();
//将Instant转换为LocalDateTime并将其设置为一天的开始
LocalDateTime dateTime=dateInstant.atZone(ZoneId.systemDefault()).toLocalDate().atStartOfDay();
//将其转换回瞬间
Instant startOfDayInstant=dateTime.atZone(ZoneId.systemDefault()).toInstant();
//返回util日期
返回日期。起始日期(startOfDayInstant);
}));
这是在您需要util date的情况下。否则,我支持michalk的答案,如果您必须使用
Date
,您仍然可以通过提供时区信息将其转换为LocalDate
Map<LocalDate, List<Order>> collect =
list.stream().collect(Collectors.groupingBy(order ->
order.getOrderDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()));
地图收集=
list.stream().collect(收集器.groupingBy(订单->
order.getOrderDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
如果必须使用Date
,您仍然可以通过提供时区信息将其转换为LocalDate
Map<LocalDate, List<Order>> collect =
list.stream().collect(Collectors.groupingBy(order ->
order.getOrderDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()));
地图收集=
list.stream().collect(收集器.groupingBy(订单->
order.getOrderDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
tl;博士
作为映射
:
order
.getDate() // Accessor method to retrieve your `java.util.Date` object.
.toInstant() // Convert from terrible legacy class `Date` to modern `java.time.Instant` class. Both represent a moment in UTC.
.atZone( // Adjust from UTC to the time zone used by your business.
ZoneId.of( "America/Los_Angeles" )
) // Remember: For any given moment, the date varies around globe by time zone, “tomorrow” in Tokyo while “yesterday” in Montréal.
.toLocalDate() // Extract the date-only portion, without time-of-day, without time zone, to use as the key in our map.
保留您的日期
会员
如果无法从java.util.Date类中更改orderDate
成员变量的类型,请使用java.time执行业务逻辑。使用添加到旧类中的新方法将日期转换为日期
不要使用LocalDateTime
其他答案中已经讨论了使用java.time,但这些答案使用了错误的类:。这完全是错误的类,因为它并不代表一个时刻。它代表了大约26-27小时范围内的潜在时刻,即全球时区的范围。该类包含日期和时间,但没有时区或UTC偏移量的概念。因此,如果一个LocalDateTime
对象在今年1月23日下午12点运行,我们不知道这是东京的中午、加尔各答的中午、巴黎的中午还是蒙特勒尔的中午——所有这些都是非常不同的时刻,相隔几个小时
要表示某个时刻,请使用以下选项之一:
瞬间
UTC中的瞬间OffsetDateTime
与UTC偏移的时刻,以小时分秒为单位ZonedDateTime
一瞬间LocalDate ld = zdt.toLocalDate() ; // The date as seen for this moment in Barstow, California.
public class Order{ private Instant whenOrdered ; //other fields + getters & setters }
Locale locale = new Locale( "fr" , "TN" ) ; // French in Tunisia. ZoneId userZone = ZoneId.of( "Africa/Tunis" ) ; // Or ZoneId.systemDefault() to get the JVM’s current default time zone (appropriate to a client machine, but not a server machine). String outputForDisplay = order .whenOrdered .atZone( userZone ) // Adjust from UTC to time zone, going from `Instant` to `ZonedDateTime`. .format( // Generate text representing the value inside our `ZonedDateTime` object. DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG ) // Let java.time automatically localize, rather than hard-code a formatting pattern. ) ;
public class Order{ private LocalDate dateOrdered ; //other fields + getters & setters }