目前,我有这个方法,我想将其转换为 Java 8 流样式(顺便说一句,我很少使用这个 API,这就是这个小练习的目的):
private static Map<Integer, List<String>> splitByWords(List<String> list) {
for (int i = 0; i < list.size(); i++) {
if(list.get(i).length() > 30 && list.get(i).contains("-")) {
mapOfElements.put(i, Arrays.stream(list.get(i).split("-")).collect(Collectors.toList()));
} else if(list.get(i).length() > 30) {
mapOfElements.put(i, Arrays.asList(new String[]{list.get(i)}));
} else {
mapOfElements.put(i, Arrays.asList(new String[]{list.get(i) + "|"}));
}
}
return mapOfElements;
}
到目前为止,这是我得到的:
private static Map<Integer, List<String>> splitByWords(List<String> list) {
Map<Integer, List<String>> mapOfElements = new HashMap<>();
IntStream.range(0, list.size())
.filter(i-> list.get(i).length() > 30 && list.get(i).contains("-"))
.boxed()
.map(i-> mapOfElements.put(i, Arrays.stream(list.get(i).split("-")).collect(Collectors.toList())));
//Copy/paste the above code twice, just changing the filter() and map() functions?
以“老式”的方式,我只需要一个for
迭代来完成我需要的关于我的条件的所有事情。有没有一种方法可以使用 Stream API 来实现,或者,如果我想坚持下去,我必须重复上面的代码,只是改变 filter() 和 map() 条件,因此有三个 for
迭代?
最佳答案
当前使用 for 循环的解决方案看起来不错。由于只需区分三种情况,因此无需概括处理。
如果有更多情况需要区分,那么重构代码就有意义了。我的方法是明确定义不同的条件及其相应的字符串处理。让我使用问题中的代码对其进行解释。
首先,我使用枚举定义了不同的条件。
public enum StringClassification {
CONTAINS_HYPHEN, LENGTH_GT_30, DEFAULT;
public static StringClassification classify(String s) {
if (s.length() > 30 && s.contains("-")) {
return StringClassification.CONTAINS_HYPHEN;
} else if (s.length() > 30) {
return StringClassification.LENGTH_GT_30;
} else {
return StringClassification.DEFAULT;
}
}
}
使用这个枚举我定义了相应的字符串处理器:
private static final Map<StringClassification, Function<String, List<String>>> PROCESSORS;
static {
PROCESSORS = new EnumMap<>(StringClassification.class);
PROCESSORS.put(StringClassification.CONTAINS_HYPHEN, l -> Arrays.stream(l.split("-")).collect(Collectors.toList()));
PROCESSORS.put(StringClassification.LENGTH_GT_30, l -> Arrays.asList(new String[] { l }));
PROCESSORS.put(StringClassification.DEFAULT, l -> Arrays.asList(new String[] { l + "|" }));
}
基于此,我可以使用请求的 IntStream
进行整个处理:
private static Map<Integer, List<String>> splitByWords(List<String> list) {
return IntStream.range(0, list.size()).boxed()
.collect(Collectors.toMap(Function.identity(), i -> PROCESSORS.get(StringClassification.classify(list.get(i))).apply(list.get(i))));
}
该方法是为字符串检索适当的 StringClassification
然后依次对应字符串处理器。字符串处理器正在实现 strategy pattern通过提供 Function<String, List<String>>
映射 String
到 List<String>
根据StringClassification
.
一个简单的例子:
public static void main(String[] args) {
List<String> list = Arrays.asList("123",
"1-2",
"0987654321098765432109876543211",
"098765432109876543210987654321a-b-c");
System.out.println(splitByWords(list));
}
输出是:
{0=[123|], 1=[1-2|], 2=[0987654321098765432109876543211], 3=[098765432109876543210987654321a, b, c]}
这使得添加或删除条件和字符串处理器变得容易。
关于java - 如何将带有条件的 for 迭代转换为 Java 8 流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52170415/