根据条件将项目从一个集合插入到另一个集合,并使用Google Guava或java 8 Stream API迭代这两个集合
我对这类物品的两个集合有一个具体案例:根据条件将项目从一个集合插入到另一个集合,并使用Google Guava或java 8 Stream API迭代这两个集合,java,collections,java-8,java-stream,guava,Java,Collections,Java 8,Java Stream,Guava,我对这类物品的两个集合有一个具体案例: public class Item { private Long id; private boolean isVisible; } 列表A包含可见项和不可见项 列表B仅包含列表A中的可见项,但顺序(索引)不同 我需要一个结果列表,其中可见项按B的相对顺序排列,不可见项的相对顺序从a开始保持不变。到目前为止,唯一正确的方法是通过迭代器: Iterator<Item> ai = A.listIterator(); Iterator
public class Item {
private Long id;
private boolean isVisible;
}
列表A包含可见项和不可见项
列表B仅包含列表A中的可见项,但顺序(索引)不同
我需要一个结果列表,其中可见项按B的相对顺序排列,不可见项的相对顺序从a开始保持不变。到目前为止,唯一正确的方法是通过迭代器:
Iterator<Item> ai = A.listIterator();
Iterator<Item> bi = B.iterator();
while(ai.hasNext() && bi.hasNext()) {
Item next = ai.next();
if (next.isVisible() && B.contains(next)) {
ai.set(bi.next())
}
}
迭代器ai=A.listIterator();
迭代器bi=B.迭代器();
while(ai.hasNext()&&bi.hasNext()){
Item next=ai.next();
if(next.isVisible()&&B.contains(next)){
ai.set(bi.next())
}
}
因此,我们将B中包含的A中的下一个可见项替换为B中的项。我想知道通过Guava或Stream API是否有更好的解决方案来解决这个问题。实现一个比较器,检查这两个项是否可见,从而都在B列表中。使用它们在B列表中的位置来确定排序顺序。如果其中一个不可见,则订单应位于列表中
class CustomSort implements Comparator<Item> {
public int compare(Item i1, Item i2) {
if (i1.isVisible() && i2.isVisible()) {
return bi.indexOf(i1) - bi.indexOf(i2);
}
return ai.indexOf(i1) - ai.indexOf(i2);
}
}
类CustomSort实现Comparator{
公共整数比较(项目i1、项目i2){
if(i1.isVisible()&&i2.isVisible()){
返回bi.indexOf(i1)-bi.indexOf(i2);
}
返回ai.indexOf(i1)-ai.indexOf(i2);
}
}
假设资本=可见,小盘股=不可见
AList={A,A,B,C,B,C,D,D,e}//可见和不可见。BList={C,D,B,A}//仅以不同的顺序可见 根据你的要求 “因此,我们将用B中的项目替换B中包含的A中的每个下一个可见项目。我想知道通过番石榴或Stream API是否有更漂亮的解决方案。” 您希望结果为-> CList={C,a,D,B,B,C,a,D,e};//根据B的命令使用可见项目 您可以首先过滤流,以仅显示可见项, 然后将该项目ID替换为该相对位置的B值。 关键是使用AtomicInteger
AtomicInteger index = new AtomicInteger();
itemA.stream().filter(a -> a.isVisible)
.forEach(a -> {
a.id = itemB.get(index.getAndIncrement()).id;
});
以下是完整代码:-
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
public class StreamExample {
public static void main(String[] args) {
List<Item> itemA = new ArrayList<>();
List<Item> itemB = new ArrayList<>();
itemA.add(new Item("A"));
itemA.add(new Item("a", false));
itemA.add(new Item("B"));
itemA.add(new Item("C"));
itemA.add(new Item("b", false));
itemA.add(new Item("c", false));
itemA.add(new Item("D"));
itemA.add(new Item("e", false));
itemB.add(new Item("C"));
itemB.add(new Item("D"));
itemB.add(new Item("B"));
itemB.add(new Item("A"));
System.out.println("BEFORE: ");
System.out.println("A: ");
itemA.forEach(System.out::print);
System.out.println("\nB: ");
itemB.forEach(System.out::print);
AtomicInteger index = new AtomicInteger();
itemA.stream().filter(a -> a.isVisible)
.forEach(a -> {
a.id = itemB.get(index.getAndIncrement()).id;
});
System.out.println("\nAFTER: ");
System.out.println("A: ");
itemA.forEach(System.out::print);
}
}
class Item {
String id;
boolean isVisible = true;
public Item(String id) {
this.id = id;
}
public Item(String id, boolean isVisible) {
this.id = id;
this.isVisible = isVisible;
}
@Override
public String toString() {
return " {'" + id + '\'' +
'}';
}
}
如果需要在listA和listB之间共享同一对象,那么可以执行以下操作 在列表中循环,
-如果a不可见,则返回a,
-如果a可见,则返回b.
然后重新组合成一个列表并替换该列表(或者根据需要创建一个新列表)
我觉得很干净,但这不是我想要的。我需要替换项目本身,而不是重置它的id。我想,下面的Angel Koh示例满足了我的需要。无论如何,谢谢你的回答!这正是我一直在寻找的。谢谢<代码>映射()函数不应该是有状态的。这将同时失败。
BEFORE:
A:
{'A'} {'a'} {'B'} {'C'} {'b'} {'c'} {'D'} {'e'}
B:
{'C'} {'D'} {'B'} {'A'}
AFTER:
A:
{'C'} {'a'} {'D'} {'B'} {'b'} {'c'} {'A'} {'e'}
AtomicInteger index = new AtomicInteger();
listA = listA.stream()
.map(a -> a.isVisible ? listB.get(index.getAndIncrement()) : a)
.collect(Collectors.toList());