Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.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 Stream - Fatal编程技术网

如何在Java流中配对不均匀列表

如何在Java流中配对不均匀列表,java,java-stream,Java,Java Stream,我有一个点列表和点之间的距离,我想做的是创建线段,其中线段由起点和终点以及两点之间的距离组成 使用简单的for循环,我可以执行以下操作: public static void main(String[] args) { List<String> points = Arrays.asList("A", "B", "C", "D"); List<Double> distances = Arrays.asList(1.5, 2.5, 3.5); for

我有一个点列表和点之间的距离,我想做的是创建线段,其中线段由起点和终点以及两点之间的距离组成

使用简单的for循环,我可以执行以下操作:

public static void main(String[] args) {
    List<String> points = Arrays.asList("A", "B", "C", "D");
    List<Double> distances = Arrays.asList(1.5, 2.5, 3.5);

    for(int x=0; x< distances.size(); x++) {
        new Segment(points.get(x), points.get(x+1), distances.get(x));
    }
}

static class Segment {
    private String startPoint;
    private String endPoint;
    private double distance;

    public Segment(String startPoint, String endPoint, double distance)
    {
        this.startPoint = startPoint;
        this.endPoint = endPoint;
        this.distance = distance;
    }
}
publicstaticvoidmain(字符串[]args){
列表点=数组;
列表距离=数组.asList(1.5,2.5,3.5);
对于(int x=0;x

但是,对于不增加代码复杂性的流,有没有一种很好的方法可以做到这一点?

您可以对流执行类似的操作:

if (points.size() - distances.size() != 1) throw new IllegalArgumentException();
List<Segment> path = IntStream.range(0, distances.size())
    .mapToObj(x -> new Segment(points.get(x), points.get(x + 1), distances.get(x)))
    .collect(Collectors.toList());
如果(points.size()-distance.size()!=1)抛出新的IllegalArgumentException();
列表路径=IntStream.range(0,distance.size())
.mapToObj(x->新线段(points.get(x)、points.get(x+1)、distance.get(x)))
.collect(Collectors.toList());

它是否增加了清晰度,或使函数变得模糊?

要对流执行此操作,您最终会执行相同的操作,即迭代索引值:

List<Segment> list = IntStream.range(0, distances.size())
        .mapToObj(x -> new Segment(points.get(x), points.get(x+1), distances.get(x)))
        .collect(Collectors.toList());
List List=IntStream.range(0,distance.size())
.mapToObj(x->新线段(points.get(x)、points.get(x+1)、distance.get(x)))
.collect(Collectors.toList());
同:

List<Segment> list = new ArrayList<>();
for (int x = 0; x < distances.size(); x++)
    list.add(new Segment(points.get(x), points.get(x+1), distances.get(x)));
List List=new ArrayList();
对于(int x=0;x

除非
new Segment()
非常慢,并且可以从并行处理中获益,否则使用流并没有获得任何好处,而且实际上运行速度较慢。

如果不使用Segment,这将是:

   List<Object> results = Stream.concat(Stream.concat(points.stream().limit(distances.size()), points.stream().skip(1)),
     distances.stream()).collect(Collectors.toList());
List results=Stream.concat(Stream.concat(points.Stream().limit(distance.size()),points.Stream().skip(1)),
distance.stream()).collect(collector.toList());

也许你们会喜欢使用第三个库(Segment除外)提供的像Tuple3这样的类。

虽然我同意其他人的观点,基于流的解决方案很可能更难阅读,但若你们经常使用它们,或者可以从对它们应用复杂的处理中获益,那个么对它们进行投资可能还是值得的

我将添加一种非基于IntStream的方法,以防您可以在这里或将来的项目中应用它:

public static Stream<Segment> zip(List<String> points, List<Double> distances)
{
    if (points == null || distances == null || points.size() - 1 != distances.size())
    {
        throw new IllegalArgumentException();
    }

    return StreamSupport.stream(new AbstractSpliterator<Segment>(distances.size(),
                                                                 Spliterator.ORDERED | Spliterator.SIZED)
    {
        private Iterator<String> pointsIterator    = points.iterator();
        private Iterator<Double> distancesIterator = distances.iterator();

        private String           previousPoint     = this.pointsIterator.next();

        @Override
        public boolean tryAdvance(Consumer<? super Segment> action)
        {
            if (!pointsIterator.hasNext())
            {
                return false;
            }

            action.accept(new Segment(previousPoint,
                                      (previousPoint = pointsIterator.next()),
                                      distancesIterator.next()));
            return true;
        }
    }, false);
}

zip(points, distances).forEach(System.out::println)
// Segment [startPoint=A, endPoint=B, distance=1.5]
// Segment [startPoint=B, endPoint=C, distance=2.5]
// Segment [startPoint=C, endPoint=D, distance=3.5]
publicstaticstreamzip(列表点、列表距离)
{
if(points==null | | distance==null | | points.size()-1!=distance.size())
{
抛出新的IllegalArgumentException();
}
return StreamSupport.stream(新的AbstractSpliterator(distance.size()),
拆分器。订购|拆分器。大小)
{
私有迭代器pointsIterator=points.Iterator();
私有迭代器distancesIterator=距离。迭代器();
私有字符串previousPoint=this.pointsIterator.next();
@凌驾

public boolean tryAdvance(消费者您编写了哪些代码来尝试此功能?我找不到一个好的方法来处理流,唯一可以干净地处理流的方法是使用上面的for循环。没有“干净”的方法来处理流;没有比您已有的更好的方法。我喜欢您的列表在视觉上对齐的方式:)这正是我想说的,在这种情况下,Stream选项实际上更难理解:(对我来说,它模糊了我遇到的墙:(@StephaneGrenier,我同意。你的原始代码清晰易懂。lambdas本质上没有更好的东西。(事实上,可能会有很多数量级的速度损失。)有时它们简洁易懂,但往往会把for循环弄得一团糟,任何初学者都能理解。这很好+1@Eugene谢谢,但显然不是每个人都这么认为。真希望他们能留下评论。