如何使用流格式化字符串,而不使用lambda?我一直在关注Formatter
,但无法找到任何只需要一根字符串的方法......所以我可以这样做:
Set<String> imported = new HashSet<>();
extendedModels.stream().filter((x)->imported.add(x))
.map(new Formatter("import {%1$s} from './%1$s';\n")::format);
我刚开始使用Java 8,所以不确定上面是否是正确的语法(引用对象的方法)。
具体来说,我寻找一种在没有lambda表达式的情况下格式化字符串的方法。原因很简单 - 因为,Java 8之前的表单只是:
for (String m : extendedModels)
if (imported.add(m))
tsWriter.write(String.format("import {%1$s} from './%1$s';\n", m));
我试图查看字符串列表,将它们缩减为唯一的*),然后在格式化的字符串中使用它们,最终写入Writer
。这就是我现在所拥有的:
这样可行,但我必须处理IOException
中的forEach
:
extendedModels.stream().filter(imported::add)
.map((x)->{return String.format("import {%1$s} from './%1$s';\n", x);})
.forEach(tsWriter::write);
所以现在我用这个:
tsWriter.write(
extendedModels.stream()
.filter(imported::add)
.map((x)->{return String.format("import {%1$s} from './%1$s';\n", x);})
.collect(Collectors.joining())
);
*)唯一性是跨多个集合,而不仅仅是extendedModels
所以我不想使用某种unique
流工具。
答案 0 :(得分:3)
至于避免使用lambda表达式并仅使用方法引用,您需要将格式化部分提取为静态或实例方法,并使用方法引用表达式引用它:
static String formatImportStatement(String imp) {
return String.format("import {%1$s} from './%1$s';\n", imp);
}
然后.map(YourClass::formatImportStatement)
。或者您也可以将labmda本身提取为如下变量:
Function<String, String> importFormatter =
(s) -> String.format("import {%1$s} from './%1$s';\n", s);
然后直接使用它:.map(importFormatter)
。
关于例外情况:
您可以使用委托Writer
包装器来软化(转换检查到未检查)异常并取消选中已检查的IOException
- s方法签名,然后将其与{{1一起使用}}
您还可以使用lambda包装器工厂来包装lambda,以使用.forEach(softeningWriter::write)
模式软化此answer中的LambdaExceptionUtil
类之类的异常。
如果您不介意首先使用.forEach(rethrowConsumer(tsWriter::write))
将导入语句收集到String
,那么您的第三个解决方案也可以正常运行。
不幸的是,您需要解决已检查的异常(至少在今天的Java8中)。也许未来的Java版本会对这些遗产做些什么,但据我所知,这并不能保证会发生。
答案 1 :(得分:0)
请注意,虽然.filter(imported::add)
看起来像一个聪明的技巧,但它是一种沮丧的技术,因为它创建了一个有状态谓词。如果您想要的是唯一性,请使用.distinct()
代替。如果您稍后需要imported
,请使用直接的收集操作创建它,即imported = new HashSet<>(extendedModels)
并在Set
上流式传输。
因此,如果您的Writer
要写入文件或任何路径,那么有一个FileSystem
实现,一个简单的解决方案就是
Set<String> imported = new HashSet<>(extendedModels);
Files.write(path, () -> imported.stream()
.<CharSequence>map(x->String.format("import {%1$s} from './%1$s';\n", x)).iterator());
或者,如果您不需要稍后设置imported
:
Files.write(path, () -> extendedModels.stream().distinct()
.<CharSequence>map(x->String.format("import {%1$s} from './%1$s';\n", x)).iterator());
如果没有Path
,即您无法避免使用预定义的Writer
,则可以使用Formatter
,但必须注意不要错过异常:
Formatter f=new Formatter(tsWriter);
extendedModels.stream().distinct().forEachOrdered(
x -> f.format("import {%1$s} from './%1$s';\n", x));
f.flush();
if(f.ioException()!=null) throw f.ioException();
无法为方法引用提供绑定参数,但由于标记String
,format
和字符串文字是不可避免的,因此无论如何都没有太大的潜在保存。