我刚刚开始使用Java 8,我正在尝试收集器上的一些示例。我跟着这本书,Java 8在行动。我对类型推断有疑问:
我使用了基本模型类Student,Name来创建示例。 PFB详情:
package com.learning.fundamentals;
import java.util.ArrayList;
import java.util.List;
public class Student {
public enum Gender {
MALE, FEMALE;
}
private String id;
private Name name;
private Gender gender;
public Student(String id, Name name, Gender gender) {
this.id = id;
this.name = name;
this.gender = gender;
}
public String getId() {
return id;
}
public Name getName() {
return name;
}
public Gender getGender() {
return gender;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((gender == null) ? 0 : gender.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (gender != other.gender)
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", gender=" + gender
+ "]";
}
}
package com.learning.fundamentals;
public class Name {
private String firstName;
private String middleName;
private String lastName;
public Name(String firstName, String middleName, String lastName) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getMiddleName() {
return middleName;
}
public String getLastName() {
return lastName;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result
+ ((lastName == null) ? 0 : lastName.hashCode());
result = prime * result
+ ((middleName == null) ? 0 : middleName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Name other = (Name) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (middleName == null) {
if (other.middleName != null)
return false;
} else if (!middleName.equals(other.middleName))
return false;
return true;
}
@Override
public String toString() {
return "Name [firstName=" + firstName + ", middleName=" + middleName
+ ", lastName=" + lastName + "]";
}
}
现在我有一份像这样的学生名单
List<Student> studentList = getStudents(); //some method to create the list
现在,让我们试一下分组示例。这是一个多级分组,首先我使用Gender对其进行分组,然后对名字进行分组(不重要)。这是代码:
Map<Student.Gender, Map<String, List<Student>>> studentsByGenderName =
studentList.stream()
.collect(Collectors.groupingBy(Student::getGender,
Collectors.groupingBy(std -> std.getName().getFirstName().substring(0, 4))));
这在第二个收集器中给出了一个错误,声明&#34;方法getName()未定义为Object&#34;类型。现在,我能够通过提供&#39; std&#39;像这样:
Map<Student.Gender, Map<String, List<Student>>> studentsByGenderName =
studentList.stream()
.collect(Collectors.groupingBy(Student::getGender,
Collectors.groupingBy((Student std) -> std.getName().getFirstName().substring(0, 4))));
我的问题是为什么java不能推断第二个收集器中使用的lambda表达式中的参数类型,而它能够为第一个收集器做到这一点?