您要做的是浏览两个同名的列表。此操作的通用名称是“zip” - 当您遍历两个(或有时更多)数组/列表/流/等并对每个元素执行某些操作时。
您可以从这里为流选择一个实现:Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip) 现有库中也已经实现了许多。如果您的项目中已经有这样的库,则只需要导入即可使用它。
出于说明目的,我假设this signature 有一个可用的实现:
<A, B, C> Stream<C> zip(Stream<? extends A> a,
Stream<? extends B> b,
BiFunction<? super A, ? super B, ? extends C> zipper)
另外,一个好的简单通用实用程序是一个有两个值的Pair 类。有许多现有的实现。我将使用此签名的实现:
class Pair<LEFT, RIGHT> {
Pair(LEFT left, RIGHT right);
LEFT getLeft();
RIGHT getRight();
}
这将保存相关的状态和地址类型。但您也可以考虑创建一个封装给定状态和地址类型的特定对象。
使用这些通用帮助器,您的代码可以如下所示:
Stream<String> states = Arrays.stream(item.getState().split(","));
Stream<String> addressType = Arrays.stream(item.getAddressType().split(","));
Map<Boolean, List<String>> splitStates = zip(states, addressTypes,
(state, addressType) -> new Pair<String, String>(state, addressType))
.collect(
Collectors.partitioningBy(pair -> Constants.MAILING.equals(pair.getRight()),
collectors.mapping(pair -> pair.getLeft())
)
);
List<String> mailingStates = split.get(true);
List<String> physicalStates = split.get(false);
如果 lambda 被替换为方法引用并在可能的情况下进行一些小的重新排列,那么您会得到:
private static final Predicate<Pair<String, String> IS_Mailing =
pair -> Constants.MAILING.equals(pair.getRight());
/* ... */
Stream<String> states = Arrays.stream(item.getState().split(","));
Stream<String> addressType = Arrays.stream(item.getAddressType().split(","));
Map<Boolean, List<String>> splitStates = zip(states, addressTypes, Pair::new)
.collect(Collectors.partitioningBy(IS_MAILING),
collectors.mapping(Pair::getLeft()));
List<String> mailingStates = split.get(true);
List<String> physicalStates = split.get(false);
如果你实现一个类而不是通用的Pair 类:
class StateData {
private String state;
private String addressType;
public StateData(String state, String addressType) {
this.state = state;
this.addressType = addressType;
}
public String getState() { return this.state; }
public String getAddressType() { return this.addressType; }
public boolean isMailing() {
return Constants.MAILING.equals(this.getAddressType());
}
}
代码变得更加语义化:
Stream<String> states = Arrays.stream(item.getState().split(","));
Stream<String> addressType = Arrays.stream(item.getAddressType().split(","));
Map<Boolean, List<String>> splitStates = zip(states, addressTypes, StateData::new)
.collect(Collectors.partitioningBy(StateData::isMailing),
collectors.mapping(StateData::getState()));
List<String> mailingStates = split.get(true);
List<String> physicalStates = split.get(false);
最后一个考虑因素是为addressType 创建一个枚举,而不是与常量进行比较。