Java 8 爪哇8流及;格式化程序或字符串::格式
如何使用流格式化字符串,而不使用lambda?我一直在查看格式化程序,但找不到任何只需要一个字符串的方法。。。所以我可以做:Java 8 爪哇8流及;格式化程序或字符串::格式,java-8,java-stream,formatter,Java 8,Java Stream,Formatter,如何使用流格式化字符串,而不使用lambda?我一直在查看格式化程序,但找不到任何只需要一个字符串的方法。。。所以我可以做: Set<String> imported = new HashSet<>(); extendedModels.stream().filter((x)->imported.add(x)) .map(new Formatter("import {%1$s} from './%1$s';\n")::format); 与问题无关的详情: 我
Set<String> imported = new HashSet<>();
extendedModels.stream().filter((x)->imported.add(x))
.map(new Formatter("import {%1$s} from './%1$s';\n")::format);
与问题无关的详情:
我试图遍历一个字符串列表,将它们简化为唯一的*)字符串,然后在格式化字符串中使用它们,最终将它们写入编写器
。以下是我现在拥有的:
这会起作用,但我必须在forEach
中处理IOException
:
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
stream util。避免使用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);
函数导入格式=
(s) ->String.format(“从“/%1$s';\n”,s导入{%1$s}”);
然后直接使用它:.map(导入格式)
关于例外情况: 您可以使用委托
编写器
包装器,该包装器软化(将选中的异常转换为未选中的异常)并从其方法签名中取消声明选中的IOException
-s,然后将其与.forEach(softeningWriter::write)
一起使用
您还可以使用lambda包装器工厂来包装lambda,以使用.forEach(rethrowConsumer(tsWriter::write))
模式来软化异常,例如这里的LambdaExceptionUtil
类
如果您不介意先使用Collectors.joining()
将导入语句收集到String
,那么第三种解决方案也可以工作
不幸的是,您需要绕过检查过的异常(至少在今天的Java8中是这样)。也许Java的未来版本会对这个遗留问题做些什么,但据我所知,这并不一定会发生。请注意,虽然
.filter(imported::add)
看起来像是一个聪明的把戏,但它是一种不受鼓励的技术,因为它创建了一个有状态谓词。如果您只需要唯一性,只需使用.distinct()
。如果以后需要导入
,请使用直接的收集操作创建它,即imported=newhashset(extendedModels)
并在集合上进行流式处理
因此,如果您的Writer
要写入一个文件或任何路径,有一个文件系统
实现,一个简单的解决方案是
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());
如果没有路径
,即无法避免使用预定义的编写器
,则可以使用格式化程序
,但必须注意不要遗漏异常:
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
和字符串文本是不可避免的,因此也没有多少潜在的保存空间。您想实现什么?是否在列表中收集一些导入语句字符串?将它们输出到一个流?哦,你想用方法引用来做任何事情,而不需要lambda表达式?有点像。为了简洁易读。这是可行的,但我找不到用于此的类。好的,谢谢,但问题是关于格式-如何避免lambda可读性较差的表达式,并使用新的格式化程序(“%s…”::Formatter是的,当然,您也可以使用Formatter
,但是您需要手动查询格式化程序以查找IOException
-s,因为Formatter
为您吞咽IOException。String.format
也“吞咽IOException
”或者您必须添加try catch
块吗?@Holger没有声明抛出IOException
,因此不需要捕获它。Formatter.format
也是如此。这就是您的语句“那么您需要手动查询格式化程序中的IOException
”的含义。对于记录,String.format(String,Object…)
实现为returnnewformatter().format(format,args).toString()代码>。因此,问题是为什么在使用格式化程序时,OP需要“手动查询格式化程序”,就像String.format
一样。
Files.write(path, () -> extendedModels.stream().distinct()
.<CharSequence>map(x->String.format("import {%1$s} from './%1$s';\n", x)).iterator());
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();