根据 Java 中的多个参数获取列表的子列表
get a sub-list of a list based on multiple parameters in Java
我有一个对象列表。每个对象都有一个级别属性(int 1、2 或 3)、一个城市属性(“纽约”、“米兰”、“伦敦”)和通用字符串 FamilyID。
列表中的对象数量是随机的。
我需要创建一个子列表(或任何其他 collection/data 结构),它由列表中的第一个对象组成,具有 Level 和 City 的任意组合(我不关心 FamilyID)。
希望通过示例使我的要求更清楚:
InitialList: [1, Milan, ID1][1, London, ID1][1, Milan, ID5][2, Lodon, ID1][2, London, ID6],[3, New York, ID2]
ExpectedOutput: [1, Milan, ID1][1, London, ID1][2, London, ID1][3, New York, ID2]
输出集合是第一个对象与(级别,城市)的任意组合的列表。
在这种情况下,您可以使用 streams
和 Collectors
。它将是这样的:
initialList.stream().collect(Collectors.toMap(City::key, city -> city, (f, s) -> f))
完整代码示例:
public class Stack {
public static void main(String[] args) {
List<City> initialList = List.of(new City(1, "Milan", "ID1"),
new City(1, "London", "ID1"),
new City(1, "Milan", "ID5"),
new City(2, "London", "ID1"),
new City(2, "London", "ID6"),
new City(3, "New York", "ID2"));
final ArrayList<City> expectedOutput = new ArrayList<>(initialList.stream().collect(Collectors.toMap(City::key, city -> city, (f, s) -> f)).values());
System.out.println(expectedOutput);
}
private static class City {
private final long level;
private final String city;
private final String family;
public City(long level, String city, String family) {
this.level = level;
this.city = city;
this.family = family;
}
public String key() {
return level + "_" + city;
}
@Override
public String toString() {
return new StringJoiner(", ", City.class.getSimpleName() + "[", "]")
.add("level=" + level)
.add("city='" + city + "'")
.add("family='" + family + "'")
.toString();
}
}
}
这里需要根据以下伪逻辑编写自定义比较器:
- 如果城市列表中的城市相同,则仅包含列表中的第一个城市(忽略第二个数组)
- 如果level相同,city不同,level和city都可以按降序排列(字符串),只对level和city的组合。
- 增加级别,对于增加的级别,再次进行级别和城市的比较,与步骤 1 和步骤 2 中的操作相同。
- 对于字符串比较,可以使用API、string1.compareTo(string2) 和return 根据负数、零或第一个字母是否小于、等于或大于正值 return 通过 compareTo 方法计算。
- New-List 就是一个像您想要的输出那样的过滤列表。
我有一个对象列表。每个对象都有一个级别属性(int 1、2 或 3)、一个城市属性(“纽约”、“米兰”、“伦敦”)和通用字符串 FamilyID。 列表中的对象数量是随机的。 我需要创建一个子列表(或任何其他 collection/data 结构),它由列表中的第一个对象组成,具有 Level 和 City 的任意组合(我不关心 FamilyID)。
希望通过示例使我的要求更清楚:
InitialList: [1, Milan, ID1][1, London, ID1][1, Milan, ID5][2, Lodon, ID1][2, London, ID6],[3, New York, ID2]
ExpectedOutput: [1, Milan, ID1][1, London, ID1][2, London, ID1][3, New York, ID2]
输出集合是第一个对象与(级别,城市)的任意组合的列表。
在这种情况下,您可以使用 streams
和 Collectors
。它将是这样的:
initialList.stream().collect(Collectors.toMap(City::key, city -> city, (f, s) -> f))
完整代码示例:
public class Stack {
public static void main(String[] args) {
List<City> initialList = List.of(new City(1, "Milan", "ID1"),
new City(1, "London", "ID1"),
new City(1, "Milan", "ID5"),
new City(2, "London", "ID1"),
new City(2, "London", "ID6"),
new City(3, "New York", "ID2"));
final ArrayList<City> expectedOutput = new ArrayList<>(initialList.stream().collect(Collectors.toMap(City::key, city -> city, (f, s) -> f)).values());
System.out.println(expectedOutput);
}
private static class City {
private final long level;
private final String city;
private final String family;
public City(long level, String city, String family) {
this.level = level;
this.city = city;
this.family = family;
}
public String key() {
return level + "_" + city;
}
@Override
public String toString() {
return new StringJoiner(", ", City.class.getSimpleName() + "[", "]")
.add("level=" + level)
.add("city='" + city + "'")
.add("family='" + family + "'")
.toString();
}
}
}
这里需要根据以下伪逻辑编写自定义比较器:
- 如果城市列表中的城市相同,则仅包含列表中的第一个城市(忽略第二个数组)
- 如果level相同,city不同,level和city都可以按降序排列(字符串),只对level和city的组合。
- 增加级别,对于增加的级别,再次进行级别和城市的比较,与步骤 1 和步骤 2 中的操作相同。
- 对于字符串比较,可以使用API、string1.compareTo(string2) 和return 根据负数、零或第一个字母是否小于、等于或大于正值 return 通过 compareTo 方法计算。
- New-List 就是一个像您想要的输出那样的过滤列表。