在 Java 8 中使用分组依据 属性
Using Group By in Java 8 with Property
package com;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GroupByDemoInJava8
{
public static void main(String args[]) throws IOException
{
List<Person> people = new ArrayList<>(); // Date Format is MM/DD/YYYY
people.add(new Person("John", "London", 21 , "2/1/18"));
people.add(new Person("Swann", "London", 21 , "3/5/18" ));
people.add(new Person("Kevin", "London", 23 , "3/12/18"));
people.add(new Person("Monobo", "Tokyo", 23 , "4/18/18"));
people.add(new Person("Sam", "Paris", 23 , "7/12/18"));
people.add(new Person("Nadal", "Paris", 31, "4/2/19"));
Map<String,List<Person>> personByCity = new HashMap<>();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
personByCity = people.stream() .collect(Collectors.groupingBy(sdf.parse(Person::getDateOfBirth)));
for (Map.Entry<String,List<Person>> entry : personByCity.entrySet()) {
System.out.println("Key = " + entry.getKey());
System.out.println("Value = " + entry.getValue());
}
}
}
class Person
{
private String name;
private String city; private int age; private String dateOfBirth;
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public Person(String name, String city, int age , String dateOfBirth)
{
this.name = name; this.city = city; this.age = age;this.dateOfBirth=dateOfBirth;
}
public String getName()
{ return name; }
public void setName(String name)
{ this.name = name; }
public String getCity()
{ return city; }
public void setCity(String city)
{ this.city = city; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }
@Override
public String toString() {
return "Person [name=" + name + ", city=" + city + ", age=" + age + "]";
}
}
不幸的是,我得到以下编译错误
- The method parse(String) in the type DateFormat is not applicable for the arguments (Person::getDateOfBirth)
- The target type of this expression must be a functional interface
如果是直接方法调用,方法引用运算符用于替换 lambda 表达式,但在您的情况下,您试图根据 sdf.parse
[=28 的结果执行 groupingBy
=]
You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it's often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
还有 SimpleDateFormat 中的 parse
方法抛出 ParseException
你需要处理它,除此之外它 returns java.util.Date
所以你需要将 return 类型更改为 Map<Date,List<Person>>
public Date parse(String source) throws ParseException
不过如果你想使用 SimpleDateFormat
你需要处理异常
Map<Date,List<Person>> personByCity = people.stream()
.collect(Collectors.groupingBy(person->{
try {
return sdf.parse(person.getDateOfBirth());
}
catch(ParseException ex){
//log error
}
return new Date();
});
我更喜欢的推荐方法是通过使用 DateTimeFormatter
使用 LocalDate
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yy");
Map<LocalDate,List<Person>> personByCity = people.stream()
.collect(Collectors.groupingBy(person->LocalDate.parse(person.getDateOfBirth(),formatter));
注意 您输入的日期字符串 "2/1/18"
和格式模式 "MM/dd/yy"
均有效,但 return 类型将根据实现,下面是例子
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yy");
LocalDate date = LocalDate.parse("02/01/18", formatter);
System.out.println(date); //2018-02-01
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
Date d = sdf.parse("02/01/18");
System.out.println(d); //Thu Feb 01 00:00:00 CST 2018
首先你说日期的格式是MM/DD/YYYY,但实际上不是。您的数据应定义为:
List<Person> people = new ArrayList<>(); // Date Format is MM/DD/YYYY
people.add(new Person("John", "London", 21, "02/01/2018"));
people.add(new Person("Swann", "London", 21, "03/05/2018"));
people.add(new Person("Kevin", "London", 23, "03/12/2018"));
people.add(new Person("Monobo", "Tokyo", 23, "04/18/2018"));
people.add(new Person("Sam", "Paris", 23, "07/12/2018"));
people.add(new Person("Nadal", "Paris", 31, "04/02/2019"));
其次不要使用 SimpleDateFormat
它已经过时了,请使用 DateTimeFormatter
and LocalDate
from java 1.8 代替:
Map<LocalDate, List<Person>> personByCity = new HashMap<>();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy");
personByCity = people.stream()
.collect(Collectors.groupingBy(p -> LocalDate.parse(p.getDateOfBirth(), dtf)));
package com;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GroupByDemoInJava8
{
public static void main(String args[]) throws IOException
{
List<Person> people = new ArrayList<>(); // Date Format is MM/DD/YYYY
people.add(new Person("John", "London", 21 , "2/1/18"));
people.add(new Person("Swann", "London", 21 , "3/5/18" ));
people.add(new Person("Kevin", "London", 23 , "3/12/18"));
people.add(new Person("Monobo", "Tokyo", 23 , "4/18/18"));
people.add(new Person("Sam", "Paris", 23 , "7/12/18"));
people.add(new Person("Nadal", "Paris", 31, "4/2/19"));
Map<String,List<Person>> personByCity = new HashMap<>();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
personByCity = people.stream() .collect(Collectors.groupingBy(sdf.parse(Person::getDateOfBirth)));
for (Map.Entry<String,List<Person>> entry : personByCity.entrySet()) {
System.out.println("Key = " + entry.getKey());
System.out.println("Value = " + entry.getValue());
}
}
}
class Person
{
private String name;
private String city; private int age; private String dateOfBirth;
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public Person(String name, String city, int age , String dateOfBirth)
{
this.name = name; this.city = city; this.age = age;this.dateOfBirth=dateOfBirth;
}
public String getName()
{ return name; }
public void setName(String name)
{ this.name = name; }
public String getCity()
{ return city; }
public void setCity(String city)
{ this.city = city; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }
@Override
public String toString() {
return "Person [name=" + name + ", city=" + city + ", age=" + age + "]";
}
}
不幸的是,我得到以下编译错误
- The method parse(String) in the type DateFormat is not applicable for the arguments (Person::getDateOfBirth)
- The target type of this expression must be a functional interface
如果是直接方法调用,方法引用运算符用于替换 lambda 表达式,但在您的情况下,您试图根据 sdf.parse
[=28 的结果执行 groupingBy
=]
You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it's often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
还有 SimpleDateFormat 中的 parse
方法抛出 ParseException
你需要处理它,除此之外它 returns java.util.Date
所以你需要将 return 类型更改为 Map<Date,List<Person>>
public Date parse(String source) throws ParseException
不过如果你想使用 SimpleDateFormat
你需要处理异常
Map<Date,List<Person>> personByCity = people.stream()
.collect(Collectors.groupingBy(person->{
try {
return sdf.parse(person.getDateOfBirth());
}
catch(ParseException ex){
//log error
}
return new Date();
});
我更喜欢的推荐方法是通过使用 DateTimeFormatter
LocalDate
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yy");
Map<LocalDate,List<Person>> personByCity = people.stream()
.collect(Collectors.groupingBy(person->LocalDate.parse(person.getDateOfBirth(),formatter));
注意 您输入的日期字符串 "2/1/18"
和格式模式 "MM/dd/yy"
均有效,但 return 类型将根据实现,下面是例子
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yy");
LocalDate date = LocalDate.parse("02/01/18", formatter);
System.out.println(date); //2018-02-01
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
Date d = sdf.parse("02/01/18");
System.out.println(d); //Thu Feb 01 00:00:00 CST 2018
首先你说日期的格式是MM/DD/YYYY,但实际上不是。您的数据应定义为:
List<Person> people = new ArrayList<>(); // Date Format is MM/DD/YYYY
people.add(new Person("John", "London", 21, "02/01/2018"));
people.add(new Person("Swann", "London", 21, "03/05/2018"));
people.add(new Person("Kevin", "London", 23, "03/12/2018"));
people.add(new Person("Monobo", "Tokyo", 23, "04/18/2018"));
people.add(new Person("Sam", "Paris", 23, "07/12/2018"));
people.add(new Person("Nadal", "Paris", 31, "04/02/2019"));
其次不要使用 SimpleDateFormat
它已经过时了,请使用 DateTimeFormatter
and LocalDate
from java 1.8 代替:
Map<LocalDate, List<Person>> personByCity = new HashMap<>();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy");
personByCity = people.stream()
.collect(Collectors.groupingBy(p -> LocalDate.parse(p.getDateOfBirth(), dtf)));