Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.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
Java 流中上一步的访问元素或传递元素,如;参数";下一步呢?_Java_Java 8_Java Stream - Fatal编程技术网

Java 流中上一步的访问元素或传递元素,如;参数";下一步呢?

Java 流中上一步的访问元素或传递元素,如;参数";下一步呢?,java,java-8,java-stream,Java,Java 8,Java Stream,访问流的前一个步骤的元素的好方法是什么 这里的示例从父对象流(字符串)开始,并将它们平面映射到每个父对象的两个子对象(整数)。在处理整数子级(forEach)的步骤中,我希望“记住”父字符串是什么(“parentFromPreviousStep”编译错误) 显而易见的解决方案是为一个字符串加上一个整数引入一个holder类,然后在flatMap中生成这样的holder对象流。但这似乎有点笨拙,我想知道是否有办法访问这样一个链中的“前一个元素”或“传递一个参数”(不引入特殊的holder类) Li

访问流的前一个步骤的元素的好方法是什么

这里的示例从父对象流(字符串)开始,并将它们平面映射到每个父对象的两个子对象(整数)。在处理整数子级(forEach)的步骤中,我希望“记住”父字符串是什么(“parentFromPreviousStep”编译错误)

显而易见的解决方案是为一个字符串加上一个整数引入一个holder类,然后在flatMap中生成这样的holder对象流。但这似乎有点笨拙,我想知道是否有办法访问这样一个链中的“前一个元素”或“传递一个参数”(不引入特殊的holder类)

List parents=new ArrayList();
父母。添加(“父母”);
父母。添加(“父母B”);
父母。添加(“父母C”);
parents.stream()
.flatMap(父级->{
List children=new ArrayList();
增加第(1)款;
增加(2);
返回children.stream();
}).forEach(child->System.out.println(child+),我的父项是:???“+parentFromPreviousStep));

背景:这实际上发生在Nashorn,其思想是为应用程序提供JavaScript脚本代码,而无需部署Java应用程序。这就是为什么我不想为我的两个业务对象(这里简化为String和Integer)引入一个特殊的Java holder类。[上面的Java代码几乎可以用Nashorn编写,流函数是Java,而不是JavaScript。]

子函数聚合到父函数,嗯。。闻起来像是键值对地图

所以,我就这样试过了。它成功了。希望这会有帮助

    parents.stream()
            .flatMap(parent -> {
                List<Integer> children = new ArrayList<>();
                children.add(1);
                children.add(2);

                Map<String, List<Integer>> stringListMap = new HashMap<String, List<Integer>>();
                stringListMap.put(parent, children);
                return stringListMap.entrySet().stream();
            })
            .forEach(entry -> {
                entry.getValue().stream().forEach(val -> System.out.println(val + ", my parent is: ???" + entry.getKey()));
            });
parents.stream()
.flatMap(父级->{
List children=new ArrayList();
增加第(1)款;
增加(2);
Map stringListMap=新建HashMap();
stringListMap.put(父级、子级);
返回stringListMap.entrySet().stream();
})
.forEach(条目->{
entry.getValue().stream().forEach(val->System.out.println(val+),我的父对象是:???“+entry.getKey());
});

霍尔格对该问题的评论提供了有价值的信息,并引出了以下解决方案。JDK中SimpleImmutableEntry的存在解决了在这种情况下创建专有holder类不是我的选择的问题。(这是一个社区维基,因为霍尔格提供了答案。)

Stream.of(“parentA”、“parentB”、“parentC”)
.flatMap(父对象->流)(
新的AbstractMap.SimpleImmutableEntry(1,父项),
新的AbstractMap.SimpleImmutableEntry(2,父级))
).forEach(child->System.out.println(child.getKey()+),我的父项是:“+child.getValue());

这在流的reducer方法中是可能的,如下所示,此代码实际上为您提供了当前元素和前两个元素的列表。 我有点惊讶,这篇文章中没有这个解决方案

public List mainfonpreviousaccess(int n){
供应商s=新供应商(){
int next=0;
@凌驾
公共整数get(){
返回next++;
}
};
返回流.generate(s).takeWhile(j->j List.of(j)).reduce((x,y)->{
System.out.println(“\n累加器x”+x);
系统输出打印项次(“y”+y);
int xs=x.size();
如果(xs>=2){
返回List.of(x.get(xs-2)、x.get(xs-1)、y.get(0));
}
返回列表(x.get(0),y.get(0));
}).get();
}

@Adligo:)

这是同一问题的另一种解决方案,它允许继续使用流,因为这不是通过终端操作完成的

public void mainFunPreviousAccess2(int n) {
    //Stream.generate(s).takeWhile(j -> j <= i).forEach(j -> System.out.println("j " + j));
    Supplier<Integer> s = new Supplier<Integer>() {
        int next = 0;
        
        @Override
        public Integer get() {
            return next++;
        }
    };

    Function<Integer, List<Integer>> s2 = new Function<Integer,List<Integer>>() {
        Integer m1 = null;
        
        @Override
        public List<Integer> apply(Integer t) {
            if (m1 == null) {
                m1 = t;
                return List.of(t);
            }
            List<Integer> r =  List.of(m1, t);
            m1 = t;
            return r;
        }
    };
    Stream.generate(s).takeWhile(k -> k <= n).map(s2).forEach(k -> System.out.println("hey " + k));
}
public void mainFunPreviousAccess2(int n){
//Stream.generate.takeWhile(j->j System.out.println(“j”+j));
供应商s=新供应商(){
int next=0;
@凌驾
公共整数get(){
返回next++;
}
};
函数s2=新函数(){
整数m1=null;
@凌驾
公共列表应用(整数t){
如果(m1==null){
m1=t;
返回列表(t);
}
列表r=列表(m1,t);
m1=t;
返回r;
}
};
Stream.generate.takeWhile(k->k System.out.println(“hey”+k));
}

@Adligo:)

如果要记住关联,需要一个存储该关联的对象。这是自然的,不可避免的方式。直到值类型进入Java场景。关于“笨拙”:你的
flatMap
功能可以简化为
parent->Stream.of(1,2)
。我知道,这只是一个例子,但是你必须创建一个
列表
并填充它,才能得到一个
,这一基本假设应该得到纠正。如果要避免使用新的专用holder类,可以使用
AbstractMap.SimpleImmutableEntry
来保存两个对象/值。@Holger:这实际上为我回答了这个问题。谢谢你的好建议!我不知道“Stream.of”和“simpleimutableentry”。你正在破坏
flatMap
的全部功能。它不打算将
List
实例传递到下游。我将
Map.Entry
对象传递到下游。在
flatMap()
中,它修饰子
列表
,并对初始流执行一些
map()
工作。我想,这就是我滥用flatMap()的原因。不是吗?您正在返回一个
。每个条目都包含一个列表。你不是在压平名单。这是最明显的,因为你是一个
Stream.of("parentA", "parentB", "parentC")
.flatMap(parent -> Stream.of(
            new AbstractMap.SimpleImmutableEntry<>(1, parent),
            new AbstractMap.SimpleImmutableEntry<>(2, parent))
).forEach(child -> System.out.println(child.getKey() + ", my parent is: " + child.getValue()));
public List<Integer> mainFunPreviousAccess(int n) {
    Supplier<Integer> s = new Supplier<Integer>() {
        int next = 0;
        
        @Override
        public Integer get() {
            return next++;
        }
    };
    return Stream.generate(s).takeWhile(j -> j <= n).map(j -> List.of(j)).reduce((x,y) -> {
        System.out.println("\naccumulator x " + x);
        System.out.println("y " + y);
        int xs = x.size();
        if (xs >= 2) {
            return List.of(x.get(xs - 2), x.get(xs -1), y.get(0));
        }
        return List.of(x.get(0), y.get(0));
    }).get();
}
public void mainFunPreviousAccess2(int n) {
    //Stream.generate(s).takeWhile(j -> j <= i).forEach(j -> System.out.println("j " + j));
    Supplier<Integer> s = new Supplier<Integer>() {
        int next = 0;
        
        @Override
        public Integer get() {
            return next++;
        }
    };

    Function<Integer, List<Integer>> s2 = new Function<Integer,List<Integer>>() {
        Integer m1 = null;
        
        @Override
        public List<Integer> apply(Integer t) {
            if (m1 == null) {
                m1 = t;
                return List.of(t);
            }
            List<Integer> r =  List.of(m1, t);
            m1 = t;
            return r;
        }
    };
    Stream.generate(s).takeWhile(k -> k <= n).map(s2).forEach(k -> System.out.println("hey " + k));
}