简体   繁体   English

像我们在C#linq中一样在Java 8中获取匿名对象

[英]Getting anonymous object in java 8 as we do in C# linq

Let's suppose I have a Person class having fields like FirstName, LastName, Age, Salary etc. Now I've this code in C# linq, where persons is a List. 假设我有一个Person类,其中包含FirstName,LastName,Age,Salary等字段。现在,我在C#linq中有了此代码,其中person是一个List。

var lstFirstAndLastNamesOnly = persons.Where(x => x.Age > 35).Select(x => new {x.FirstName, x.LastName}).ToList();

This is going to get me an anonymous type having FirstName and LastName. 这将使我得到具有FirstName和LastName的匿名类型。 How do I write something like this in Java 8? 如何在Java 8中编写类似的内容? What could be the better ways so as only a handful of fields are returned when I have say 100 fields on the class. 有什么更好的方法,当我在课堂上说100个字段时,只返回少数几个字段。

Well, the Java programming language has anonymous types, but they aren't as useful as in that C# example. 好的,Java编程语言具有匿名类型,但是它们不像该C#示例中那样有用。 Ie, the following would work: 即,以下方法将起作用:

persons.stream().filter(x -> x.age > 35)
    .map(x -> new Object(){ String first=x.firstName, last=x.lastName; })
    .forEach(name -> System.out.println(name.first+" "+name.last));

As you will notice, the declaration of an anonymous type still requires a type specification, which will be the supertype of the anonymous type. 您将注意到,匿名类型的声明仍然需要类型说明,这将是匿名类型的超类型。 Further, you have to formally declare the members holding the data with type and name. 此外,您必须使用类型和名称正式声明保存数据的成员。

Also, lambda expressions are the only place where you can declare a variable (the parameters) without specifying their type and letting the compiler infer it. 另外,lambda表达式是唯一可以声明变量(参数)而无需指定变量类型并让编译器进行推断的地方。

Since the relevant property of an anonymous type is to have no name, you can't declare a variable of that type, when an explicit type is required. 由于匿名类型的相关属性没有名称,因此当需要显式类型时,您不能声明该类型的变量。 And the Java programming language does not have the var name declaration syntax. 而且Java编程语言没有var name声明语法。

You may access it in a fluent context, without a variable, like 您可以在流畅的上下文中访问它,而无需使用变量,例如

System.out.println(
    persons.stream().filter(x -> x.age > 35)
        .map(x -> new Object(){ String a=x.firstName, b=x.lastName; })
        .findFirst().get().a
);

but since this only allows accessing a single member, it's of little use, as, if you only need a single member, you could just map to the member value in the first place. 但这只允许访问一个成员,因此没有什么用,因为如果只需要一个成员,则可以首先map到成员值。

In this specific example, you could use a two element String array instead: 在此特定示例中,您可以使用两个元素的String数组代替:

List<String[]> lstFirstAndLastNamesOnly = persons.stream()
    .filter(x -> x.age > 35)
    .map(x -> new String[] { x.firstName, x.lastName })
    .collect(Collectors.toList());
lstFirstAndLastNamesOnly
    .forEach(name -> System.out.println(name[0]+" "+name[1]));

but, of course, they are no replacement for real tuples, especially when you have heterogeneously typed elements. 但是,当然,它们不能替代真正的元组,尤其是当您具有异构类型的元素时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM