Java 按元素将列表拆分为块
我有一组使用此模型的对象(Pos):Java 按元素将列表拆分为块,java,collections,split,java-8,java-stream,Java,Collections,Split,Java 8,Java Stream,我有一组使用此模型的对象(Pos): public class Pos { private String beforeChangement; private String type; private String afterChangement; } 对象列表如下所示: [ Pos(beforeChangement=Découvrez, type=VER, afterChangement=découvrir), Pos(beforeChangement=un, typ
public class Pos {
private String beforeChangement;
private String type;
private String afterChangement;
}
对象列表如下所示:
[
Pos(beforeChangement=Découvrez, type=VER, afterChangement=découvrir),
Pos(beforeChangement=un, type=DET, afterChangement=un),
Pos(beforeChangement=large, type=ADJ, afterChangement=large),
Pos(beforeChangement=., type=SENT, afterChangement=.),
Pos(beforeChangement=Livraison, type=NOM, afterChangement=livraison),
Pos(beforeChangement=et, type=KON, afterChangement=et),
Pos(beforeChangement=retour, type=NOM, afterChangement=retour),
Pos(beforeChangement=., type=SENT, afterChangement=.),
Pos(beforeChangement=achetez, type=VER, afterChangement=acheter),
Pos(beforeChangement=gratuitement, type=ADV, afterChangement=gratuitement),
Pos(beforeChangement=., type=SENT, afterChangement=.),
Pos(beforeChangement=allez, type=VER, afterChangement=aller),
Pos(beforeChangement=faites, type=VER, afterChangement=faire),
Pos(beforeChangement=vite, type=ADV, afterChangement=vite),
Pos(beforeChangement=chers, type=ADJ, afterChangement=cher),
Pos(beforeChangement=clients, type=NOM, afterChangement=client)]
Pos(beforeChangement=., type=SENT, afterChangement=.)
]
List<List<Pos>> result = new ArrayList<>();
List<Pos> part = new ArrayList<>();
for(Pos pos : listPos){
if(pos.getBeforeChangement().equals(".") || pos.getAfterChangement().equals(".")){
result.add(part);//If the condition is correct then add the sub list to result list
part = new ArrayList<>();// and reinitialize the sub-list
} else {
part.add(pos);// else just put the Pos object to the sub-list
}
}
//Just in case the listPos not end with "." values then the last part should not be escaped
if(!part.isEmpty()){
result.add(part);
}
我想按beforeChangement或afterChangement==“”字段拆分此对象列表,以获得此格式(列表列表列表)List
:
类似于执行一个反向平面映射,在按字符串“对象”字段进行拆分后,生成一个数组或列表(块)列表
你知道如何使用Streams吗
谢谢大家假设列表中的对象名为
SOP
对象名为listSOP
。然后
List<SOP> listSOP = new ArrayList<>();
.... populate your list.
Map<String,List<SOP>> map = listSOP.stream().collect(Collectors.groupingBy(SOP::getBeforeChangement)
List listSOP=new ArrayList();
.... 填充您的列表。
Map Map=listSOP.stream().collect(收集器.groupingBy(SOP::getBeforeChangement)
这将返回类型为
的映射
这里的getBeforeChangement
是SOP
类中的getter方法,它应该返回变量beforeChangement
的值,这可能会对您有所帮助。好吧,我在这里会保守一些,我不会使用流
s(尽管这是可能的)
以下代码段满足您的需要:
List<Pos> posList;
List<List<Pos>> result = new ArrayList<>();
boolean startNewSentence = true;
for (Pos pos : posList) {
if (startNewSentence) {
result.add(new ArrayList<>());
}
startNewSentence = isPeriod(pos);
if (!startNewSentence) {
result.get(result.size() - 1).add(pos);
}
}
注:英语中没有“changement”这样的词。动词“change”中的名词也是“。嗯,我想用这样一个简单的循环来解决你的问题:
[
Pos(beforeChangement=Découvrez, type=VER, afterChangement=découvrir),
Pos(beforeChangement=un, type=DET, afterChangement=un),
Pos(beforeChangement=large, type=ADJ, afterChangement=large),
Pos(beforeChangement=., type=SENT, afterChangement=.),
Pos(beforeChangement=Livraison, type=NOM, afterChangement=livraison),
Pos(beforeChangement=et, type=KON, afterChangement=et),
Pos(beforeChangement=retour, type=NOM, afterChangement=retour),
Pos(beforeChangement=., type=SENT, afterChangement=.),
Pos(beforeChangement=achetez, type=VER, afterChangement=acheter),
Pos(beforeChangement=gratuitement, type=ADV, afterChangement=gratuitement),
Pos(beforeChangement=., type=SENT, afterChangement=.),
Pos(beforeChangement=allez, type=VER, afterChangement=aller),
Pos(beforeChangement=faites, type=VER, afterChangement=faire),
Pos(beforeChangement=vite, type=ADV, afterChangement=vite),
Pos(beforeChangement=chers, type=ADJ, afterChangement=cher),
Pos(beforeChangement=clients, type=NOM, afterChangement=client)]
Pos(beforeChangement=., type=SENT, afterChangement=.)
]
List<List<Pos>> result = new ArrayList<>();
List<Pos> part = new ArrayList<>();
for(Pos pos : listPos){
if(pos.getBeforeChangement().equals(".") || pos.getAfterChangement().equals(".")){
result.add(part);//If the condition is correct then add the sub list to result list
part = new ArrayList<>();// and reinitialize the sub-list
} else {
part.add(pos);// else just put the Pos object to the sub-list
}
}
//Just in case the listPos not end with "." values then the last part should not be escaped
if(!part.isEmpty()){
result.add(part);
}
List result=new ArrayList();
列表部分=新的ArrayList();
用于(位置:列表位置){
如果(位置getBeforeChangement()等于(“.”)| |位置GetAfterChange()等于(“.”){
result.add(part);//如果条件正确,则将子列表添加到结果列表中
part=new ArrayList();//并重新初始化子列表
}否则{
part.add(pos);//否则只需将pos对象放入子列表
}
}
//如果listPos不以“.”值结尾,则不应转义最后一部分
如果(!part.isEmpty()){
结果.增加(部分);
}
注意,问题还不够清楚,您的对象类名为SOP
,对象列表是Pos
哪一个是正确的,在我的回答中,我基于公共类Pos{..}
而不是公共类SOP{..}
使用库,您可以使用方法为列表列表拆分列表
例如:
List<List<Pos>> collect = StreamEx.of(originalList.stream())
.groupRuns((p1, p2) -> !(".".equals(p2.beforeChangement) || ".".equals(p2.afterChangement)))
.collect(Collectors.toList());
这将不起作用:它将把所有的SOP
s与相同的beforeChangement
组合在一起,而不是将原始列表划分为有序的子列表。谢谢Tomasz。这个逻辑可以解决我的问题+1@Dr.Mza我更新了代码,所以结果中不包括带句点的元素。谢谢你的回答纠正Pos和SOP是相同的。此解决方案存在一个重大问题,即当Pos
列表不以
结尾时,您的代码将跳过最后一句话。No@TomaszLinkowski检查问题中的输出,结果中不包括具有
的对象。您还可以与我的回答中提到的问题的输出和演示的输出相比,你是对的,根据问题,包含
的对象应该被跳过(我没有注意到,我的答案也没有)。但我的意思是,如果输入列表没有以“点”结尾-对象,您的代码只是跳过了整个最后一个子列表,而不是包含这样的子列表或抛出错误。请参阅,我从listPos
中删除了最后一行。请注意“allez”、“faites”、“vite”、“chers”、“clients”输出中缺少了
。但据我所知,此代码将把点放在单独的列表中,对吗?我们如何排除管道中的“.”而不是与点相关的
映射过滤器(以及额外的收集),我只需使用以下命令:过滤器(l->!isPeriod(l.get(0)))
whereboolean isPeriod(Pos-Pos){return.“.equals(Pos.beforeChangement)| |”。.equals(Pos.afterChangement);}
@TomaszLinkowski您的示例是,如果第一个元素是“”,则过滤掉整个列表。“-元素现在我更仔细地阅读了代码,我明白句点并没有放在单独的列表中。我感到困惑,因为我认为groupRuns
中的谓词是(p1,p2)->!isPeriod(p1)&!isPeriod(p2)
而实际上它是(p1,p2)->!isPeriod(p2)
。这是一种有点奇怪的情况,因为它意味着句点在列表的开头。但是,你是对的,我的筛选建议不起作用。相反,我会将谓词更改为(p1,p2)->!isPeriod(p1)
,然后使用peek
从每个列表中删除最后一个元素(如果它匹配isPeriod
)。
StreamEx.of(originalList.stream())
.groupRuns((p1, p2) -> !(".".equals(p2.beforeChangement) || ".".equals(p2.afterChangement))) // returns Stream of lists with '.' element
.map(l -> l.stream()
.filter(p -> !(".".equals(p.beforeChangement) || ".".equals(p.afterChangement))) //filter out element with '.'
.collect(Collectors.toList()))
.filter(l -> !l.isEmpty()) // filter out empty lists
.collect(Collectors.toList());