gpt4 book ai didi

java - 什么等同于 C#'s Select clause in JAVA' s 流 API

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:05:40 26 4
gpt4 key购买 nike

我想过滤 Person 类的列表,最后使用 Streams 映射到 Java 中的某个匿名类。我能够在 C# 中非常轻松地完成同样的事情。

人物类

class Person
{
public int Id { get; set; }

public string Name { get; set; }

public string Address { get; set; }
}

以所需格式映射结果的代码。

 List<Person> lst = new List<Person>();

lst.Add(new Person() { Name = "Pava", Address = "India", Id = 1 });
lst.Add(new Person() { Name = "tiwari", Address = "USA", Id = 2 });
var result = lst.Select(p => new { Address = p.Address, Name = p.Name }).ToList();

现在,如果我想访问新创建类型的任何属性,我可以使用下面提到的语法轻松访问。

Console.WriteLine( result[0].Address);

理想情况下,我应该使用循环来迭代结果。

我知道在 java 中,我们为 ToList 收集数据,为 Select 映射数据。但是我无法只选择 Person 类的两个属性。我该怎么做 Java

最佳答案

Java 没有结构类型。您可以将值映射到的最接近的是匿名类的实例。但也有明显的缺点。从 Java 16 开始,使用 record将是更好的解决方案,即使它是命名类型并且可能稍微冗长一些。

例如假设

class Person {
int id;
String name, address;

public Person(String name, String address, int id) {
this.id = id;
this.name = name;
this.address = address;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
}

你可以做到

List<Person> lst = List.of(
new Person("Pava", "India", 1), new Person("tiwari", "USA", 2));
var result = lst.stream()
.map(p -> {
record NameAndAddress(String name, String address){}
return new NameAndAddress(p.getName(), p.getAddress());
})
.collect(Collectors.toList());
result.forEach(x -> System.out.println(x.name() + " " + x.address()));

匿名内部类替代方案看起来像

List<Person> lst = List.of(
new Person("Pava", "India", 1), new Person("tiwari", "USA", 2));
var result = lst.stream()
.map(p -> new Object(){ String address = p.getAddress(); String name = p.getName();})
.collect(Collectors.toList());
result.forEach(x -> System.out.println(x.name + " " + x.address));

但是您可能会注意到,它仍然不如结构类型那么简洁。声明 result变量使用 var是引用我们无法通过名称引用的类型的唯一方法。这需要 Java 10 或更高版本,并且仅限于方法的范围。

同样重要的是要记住,内部类会由于捕获对周围 this 的引用而造成内存泄漏。 .在示例中,每个对象还捕获了 p 的值。用于它的初始化。 record没有这些问题,而且它会自动变得合适equals , hashCode , 和 toString实现,这意味着打印像 System.out.println(result); 这样的列表或将其转移到像 new HashSet<>(result) 这样的集合中将产生有意义的结果。

此外,移动 record 更容易的声明范围更广。

在 Java 10 之前,lambda 表达式是唯一支持声明隐含类型变量(可以是匿名的)的 Java 功能。例如,即使在 Java 8 中,以下内容也可以工作:

List<String> result = lst.stream()
.map(p -> new Object(){ String address = p.getAddress(); String name = p.getName();})
.filter(anon -> anon.name.startsWith("ti"))
.map(anon -> anon.address)
.collect(Collectors.toList());

关于java - 什么等同于 C#'s Select clause in JAVA' s 流 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43973776/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com