Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
根据条件将项目从一个集合插入到另一个集合,并使用Google Guava或java 8 Stream API迭代这两个集合_Java_Collections_Java 8_Java Stream_Guava - Fatal编程技术网

根据条件将项目从一个集合插入到另一个集合,并使用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());