- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一些 Java 代码可以根据某些输入过滤列表。它目前使用 lambda,例如:
public List<ComplexObject> retrieveObjectsFilteredByTags(List<String> allowedTags) {
List<ComplexObject> complexObjects = retrieveAllComplexObjects();
return complexObjects
.stream()
.filter( compObject -> allowedTags.contains(compObject.getTag()))
.collect(Collectors.toList());
}
我想做的是将过滤器逻辑移动到另一种方法,使其可重用且易于单元测试。所以我想使用方法引用来代替传递给过滤器方法的 lambda。如果过滤器逻辑相当静态(即允许的标签列表在编译时已知),则很容易做到,但我无法弄清楚如何使用过滤器中的动态数据执行此操作。
我想要的是使用方法引用然后传递第二个动态参数的某种方式,即
public List<ComplexObject> retrieveObjectsFilteredByTags(List<String> allowedTags) {
List<ComplexObject> complexObjects = retrieveAllComplexObjects();
return complexObjects
.stream()
.filter(this::filterByAllowedTags, allowedTags)
.collect(Collectors.toList());
}
那么是否有可能做我想做的事,或者我是否可能错误地处理了这种情况?
最佳答案
我建议传入一个 Predicate
作为参数。这样调用者就可以根据它想要的任何标准进行过滤,包括 allowedTags
或其他任何东西:
public List<ComplexObject> retrieveObjectsFilteredBy(Predicate<ComplexObject> pred) {
List<ComplexObject> complexObjects = retrieveAllComplexObjects();
return complexObjects.stream()
.filter(pred)
.collect(Collectors.toList());
}
这样调用:
List<String> allowedTags = ... ;
List<ComplexObject> result =
retrieveObjectsFilteredBy(cobj -> allowedTags.contains(cobj.getTag()));
但您可以走得更远,这取决于您愿意进行多少重构。与其“检索”返回一个 List
,不如让它返回一个 Stream
怎么样?而不是 retrieve-filter 方法返回一个 List
,让它也返回一个 Stream
怎么样?
public Stream<ComplexObject> retrieveObjectsFilteredBy2(Predicate<ComplexObject> pred) {
Stream<ComplexObject> complexObjects = retrieveAllComplexObjects2();
return complexObjects.filter(pred);
}
调用方看起来像这样:
List<String> allowedTags = ... ;
List<ComplexObject> result =
retrieveObjectsFilteredBy2(cobj -> allowedTags.contains(cobj.getTag()))
.collect(toList());
现在,如果您仔细观察它,您会发现 retrieve-filter 方法根本没有添加任何值,因此您不妨将它内联到调用者中:
List<String> allowedTags = ... ;
List<ComplexObject> result =
retrieveAllComplexObjects2()
.filter(cobj -> allowedTags.contains(cobj.getTag()))
.collect(toList());
当然,根据调用者想要做什么,它可能不想将结果收集到列表中;它可能希望使用 forEach()
或其他方式处理结果。
现在你仍然可以将过滤器分解到它自己的方法中,用于测试/调试,你可以使用方法引用:
boolean cobjFilter(ComplexObject cobj) {
List<String> allowedTags = ... ;
return allowedTags.contains(cobj.getTag());
}
List<ComplexObject> result =
retrieveAllComplexObjects2()
.filter(this::cobjFilter)
.collect(toList());
如果您不希望过滤器内置允许的标签,您可以将其从谓词更改为返回谓词的高阶函数:
Predicate<ComplexObject> cobjFilter(List<String> allowedTags) {
return cobj -> allowedTags.contains(cobj.getTag());
}
List<String> allowedTags = ... ;
List<ComplexObject> result =
retrieveAllComplexObjects2()
.filter(cobjFilter(allowedTags))
.collect(toList());
这些变化中的哪一个最有意义取决于您的应用程序的外观以及您在过滤中需要什么样的动态性。
关于java - 如何将具有动态值的 lambda 过滤器转换为方法引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26634741/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!