我有一个这样的模型:
public class Contact {
private int id;
private String firstName;
private String lastName;
private String address;
private String city;
private String state;
private String zipCode;
private String mobilePhone;
private String email;
private String dayOfBirth;
private int age;
public String toLine() {
return String.format("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s", id, firstName, lastName, dayOfBirth, address, city, state, zipCode, mobilePhone, email);
}
}
我编写了一个sort函数,通过使用反射按字段名称对List进行排序,但是field.get(contact1)
没有方法compareTo。有什么方法可以实现吗? BTW,任何使toLine功能更短的方法?它似乎太长了。
public void sortByFieldName(String fieldName, List<Contact> validContacts) throws NoSuchFieldException {
Field field = Contact.class.getDeclaredField(fieldName);
field.setAccessible(true);
validContacts.stream().sorted((contact1, contact2) -> field.get(contact1).compareTo(field.get(contact2)));
}
我不想使用它,因为它似乎不灵活:
if (fieldName.equals("zipCode")) {
validContacts.sort(Comparator.comparing(Contact::getZipCode));
}
我删除了getter和setter,因为它太长了
答案 0 :(得分:1)
你根本不需要任何反思。您可以使用Comparator#comparing
:
List<Contact> sortedContacts = validContacts.stream()
.sorted(Comparator.comparing(Contact::getZipCode))
.collect(Collectors.toList());
当然,这假设你的班级有getter方法,而你的问题并没有。如果是这种情况且可以访问字段,您也可以使用c -> c.zipCode
代替Contact::getZipCode
。如果两者都不是这样,并且该类看起来像你所显示的那样,那么这些字段将毫无用处,因为没有人可以访问它们(除非它是另一个类中的静态类)。
如果你确实需要使用反射 - 我真的认为你不 - 这样做,那么你就可以这样做。但我要说这是更具体的,不可重复使用。如上所示使用流API会更好:
public static List<Contact> sortByFieldName(List<Contact> list, String fieldName) throws NoSuchFieldException {
Field field = Contact.class.getDeclaredField(fieldName);
if (!String.class.isAssignableFrom(field.getType())) {
throw new IllegalArgumentException("Field is not a string!");
}
field.setAccessible(true);
return list.stream()
.sorted((first, second) -> {
try {
String a = (String) field.get(first);
String b = (String) field.get(second);
return a.compareTo(b);
} catch (IllegalAccessException e) {
throw new RuntimeException("Error", e);
}
})
.collect(Collectors.toList());
}