列表流未正确筛选。

huangapple go评论79阅读模式
英文:

List stream does not filter correct

问题

我在流式处理时遇到了关于 List 的问题。如果我减少流的操作,那么我可以得到正确的结果,但是如果我对流进行筛选并调用 findFirst() 方法,我会得到一个空的结果。为什么会这样?我做错了什么?

Index - 包含映射数据的类:

public class Index {

    private final Map<String, String> data = new HashMap<>();

    public String getData(String name) {
        return data.getOrDefault(name, "");
    }

    public Set<String> getDataNames() {
        return data.keySet();
    }

    @Override
    public String toString() {
       return data.toString();
    }
}

IndexList - 包含 Index 对象的列表,通过在 Main 类中调用 load() 方法来填充:

public enum IndexList {

    INDICES_0("First list", new LinkedList<>(Arrays.asList("name", "surname", "an")));

    private List<Index> loaded;
    private final String name;
    private final Queue<String> nameQueue;

    IndexList(String name, Queue<String> nameQueue) {
        this.name = name;
        this.nameQueue = nameQueue;
    }

    public Index get(int id) {
        return loaded.get(id-1);
    }

    public List<Index> getLoaded() {
        return loaded;
    }

    public void load() {
        this.loaded = new LinkedList<>();
        
        // ... > 从 xml 文件加载数据

        List<Index> loaded = this.loaded;
        this.loaded = new ArrayList<>(loaded);
        loaded.clear();
    }

    public Queue<String> queueNames() {
        return new LinkedList<>(nameQueue);
    }

    public String getName() {
        return name;
    }
}

在正常运行时,我应该在 GUI 中看到一些 Index 对象,但实际上没有显示出来。因此,我在调试器中运行了程序并添加了监视变量。

在调试器中

IndexList.INDICES_0.loaded.size() = 558
IndexList.INDICES_0.loaded.stream().get(0) = {Index@1700} "{surname=Smith, name=John, an=1/2000}"
IndexList.INDICES_0.loaded.stream().reduce((i0, i1) -> i1.getData("surname").equals("Smith") && i1.getData("name").equals("John") ? i1 : i0) = {Optional@1623} "Optional[{surname=Smith, name=John, an=1/2000}]"
IndexList.INDICES_0.loaded.stream().filter(i -> i.getData("surname").equals("Smith") && i.getData("name").equals("John")).findFirst() = {Optional@1640} "Optional.empty"
英文:

I have problem with List when I'm streaming. If I reduce stream then I get correct result, but if I filter stream and invoke findFirst() I get empty result. Why? What do I do wrong?

Index - contains data in map:

public class Index {

    private final Map&lt;String, String&gt; data = new HashMap&lt;&gt;();
    
    public String getData(String name) {
        return data.getOrDefault(name, &quot;&quot;);
    }
    
    public Set&lt;String&gt; getDataNames() {
        return data.keySet();
    }
    
    @Override
    public String toString() {
       return data.toString();
    }
}

IndexList - contains Index objects in list, filling is invoke load() method in Main class:

public enum IndexList {

    INDICES_0(&quot;First list&quot;, new LinkedList&lt;&gt;(Arrays.asList(&quot;name&quot;, &quot;surname&quot;, &quot;an&quot;)));

    private List&lt;Index&gt; loaded;
    private final String name;
    private final Queue&lt;String&gt; nameQueue;

    IndexList(String name, Queue&lt;String&gt; nameQueue) {
        this.name = name;
        this.nameQueue = nameQueue;
    }

    public Index get(int id) {
        return loaded.get(id-1);
    }

    public List&lt;Index&gt; getLoaded() {
        return loaded;
    }

    public void load() {
        this.loaded = new LinkedList&lt;&gt;();
        
        // ... &gt; loading from xml file

        List&lt;Index&gt; loaded = this.loaded;
        this.loaded = new ArrayList&lt;&gt;(loaded);
        loaded.clear();
    }

    public Queue&lt;String&gt; queueNames() {
        return new LinkedList&lt;&gt;(nameQueue);
    }

    public String getName() {
        return name;
    }
}

I normal run I saw some Index object should be show in GUI, but it did not. So I ran program in debugger and added watches.

In debugger:

IndexList.INDICES_0.loaded.size() = 558
IndexList.INDICES_0.loaded.stream().get(0) = {Index@1700} &quot;{surname=Smith, name=John, an=1/2000}&quot;
IndexList.INDICES_0.loaded.stream().reduce((i0, i1) -&gt; i1.getData(&quot;surname&quot;).equals(&quot;Smith&quot;) &amp;&amp; i1.getData(&quot;name&quot;).equals(&quot;John&quot;)? i1 : i0) = {Optional@1623} &quot;Optional[{surname=Smith, name=John, an=1/2000}]&quot;
IndexList.INDICES_0.loaded.stream().filter(i -&gt; i.getData(&quot;surname&quot;).equals(&quot;Smith&quot;) &amp;&amp; i.getData(&quot;name&quot;).equals(&quot;John&quot;)).findFirst() = {Optional@1640} &quot;Optional.empty&quot;

答案1

得分: 0

我解决了问题:在字符串集合中有UTF-8 BOM字符,并且相同的姓氏出现在不同的位置。因此,reduce方法在流中返回了第一个对象。

英文:

I resolved problem: in set of strings were UTF-8 BOM characters and the same surnames was in different places.
So, reduce method returned the first object in stream.

huangapple
  • 本文由 发表于 2020年8月17日 06:15:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63442413.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定