Java流中多个数组内的循环

Java流中多个数组内的循环,java,java-stream,Java,Java Stream,我需要一些帮助来优化遍历200行列表的方法。 我的第一节课如下 Class Vehicle Date date int nbOfVehicleArriving Class Planning int date int nbOfallowedVehicles 因此,我有一个每次到达的车辆列表,例如: 01/01/2018 00:00:00 12 01/01/2018 00:10:00 10 01/01/2018 01:00:00 5 01/01/2018 01:10:00 10 ...

我需要一些帮助来优化遍历200行列表的方法。 我的第一节课如下

Class Vehicle
 Date date
 int nbOfVehicleArriving


Class Planning
 int date
 int nbOfallowedVehicles
因此,我有一个每次到达的车辆列表,例如:

01/01/2018 00:00:00 12
01/01/2018 00:10:00 10
01/01/2018 01:00:00 5
01/01/2018 01:10:00 10
....
我有一些议程

01/01/2018 00:00:00 3
01/01/2018 00:10:00 2
01/01/2018 01:00:00 3
01/01/2018 01:10:00 5
我需要计算排队的车辆数量

我计划做的是迭代车辆,然后在其中迭代规划

有更好的方法吗

提前谢谢

您可以试试这个

Map<Date, Integer> agendasByDate = agendas.stream()
        .collect(Collectors.toMap(Planning::getDate, Planning::getNbOfallowedVehicles));

Map<Date, Integer> vehiclesInQueueByDate = vehicles.stream().collect(Collectors.toMap(Vehicle::getDate,
        v -> v.getNbOfVehicleArriving() - agendasByDate.get(v.getDate())));
Map agendasByDate=agents.stream()
.collect(Collectors.toMap(Planning::getDate,Planning::getNbOfallowedVehicles));
Map vehiclesInQueueByDate=vehicles.stream().collect(收集器)toMap(车辆::getDate,
v->v.getnbofvehiclarriving()-agendasByDate.get(v.getDate());

您还可以使用
flatMap
将两个数组合并在一起,然后简单地提取计数(这将涉及强制转换)并将其相加

下面是一个完整的工作示例,演示如何使用
flatMap

import java.util.Arrays;
import java.util.Date;
import java.util.stream.Stream;

public class MergeStreams {

    public static void main(String[] args) {
        Vehicle[] vehicles = {new Vehicle(new Date(), 10), new Vehicle(new Date(), 11)};
        Planning[] plannings = {new Planning(new Date(), 5), new Planning(new Date(), 12)};
        int sum = Stream.of(vehicles, plannings)
            .flatMap(Arrays::stream)
            .map(object -> object instanceof Vehicle ? ((Vehicle) object).getNbOfVehicleArriving() : ((Planning) object).getNbOfallowedVehicles())
            .mapToInt(Integer::intValue)
            .sum();
        System.out.println(sum);
    }
}

class Vehicle {
    private Date date;
    private int nbOfVehicleArriving;

    public Vehicle(Date date, int nbOfVehicleArriving) {
        this.date = date;
        this.nbOfVehicleArriving = nbOfVehicleArriving;
    }

    public int getNbOfVehicleArriving() {
        return nbOfVehicleArriving;
    }
}


class Planning {
    private Date date;
    private int nbOfallowedVehicles;

    public Planning(Date date, int nbOfallowedVehicles) {
        this.date = date;
        this.nbOfallowedVehicles = nbOfallowedVehicles;
    }

    public int getNbOfallowedVehicles() {
        return nbOfallowedVehicles;
    }
}

如果您运行此示例,它将在控制台上输出
38

对于200行,您选择的解决方案可能没有任何区别。但是,如果您想要一个可以扩展到很长列表的解决方案,正确的方法是将两个列表(或流)压缩到一起(这样可以避免循环两次),并使用函数生成组合结果。番石榴本身提供了一种方法,但你也可以自己编写

我不确定你所说的“排队车辆数量”是什么意思,但我假设你想知道最后还有多少车辆没有被允许进入

您可以创建自己的类,该类映射到达的车辆以及该日期的日程

public class VehiclePlanningData {

    private final Vehicle vehicle;
    private final Planning planning;

    public  VehiclePlanningData(Vehicle vehicle, Planning planning) {
        this.vehicle = vehicle;
        this.planning = planning;
    }

    public Vehicle getVehicle() {
        return vehicle;
    }

    public Planning getPlanning() {
        return planning;
    }
}
一旦有了此功能,您就可以轻松地执行
reduce()
操作,以结转上一个插槽中剩余的所有车辆

类似这样的东西(使用Guava Streams类):

更新:

似乎队列是每个时间段的。在这种情况下,您可能希望有一个这样的特殊类,它存储每个插槽的队列大小:

public class TimeslotQueue {
   private final Date date;
   private final int queueSize;

   public VehicleQueue(Date date, int queueSize) {
     this.date = date;
     this.queueSize = queueSize;
   }

   public Date getDate() { 
     return date;
   }

   public int getQueueSize() {
     return queueSize;
   }
 }
然后得到如下这些类的流:

    List<TimeslotQueue> queues = Streams.zip(vehicles.stream(), planning.stream(), 
         (v, p) -> new TimeslotQueue(v.getDate(), 
                        v.getNbOfVehicleArriving() - p.getNbOfallowedVehicles()))
         .collect(Collectors.toList());
List queues=Streams.zip(vehicles.stream(),planning.stream(),
(v,p)->新的TimeslotQueue(v.getDate(),
v、 GetNbofVehicle驾驶()-p.getNbOfallowedVehicles())
.collect(Collectors.toList());

这样,您就有了每个日期排队车辆的列表。作为旁注,我将使用Java8
LocalDateTime
而不是旧的
Date

对于使用以日期为键的映射,您有什么想法?如果您正在寻找优化,请不要使用java流。做一个谷歌搜索,你会发现很多关于流函数有多慢的文章和比较。@Jorge.V说“流很慢,不要使用它们”的概括肯定是不正确的。这是一个用例的问题。@Ben,我不同意。没有一种情况下,流速度不会慢很多。充其量,它们接近于命令。查看200行的输入速度可能根本不重要。表达能力通常更重要。我认为我的问题不够清楚。我想得到每分钟的总和。不是全部。。因此,对于每个车辆的时间戳,我可以计算出队列中剩余的车辆数量,您需要准确获取什么?2018年1月1日00:00:00 12-3=队列中的9辆2018年1月1日00:10:00 10-2=队列中的8辆2018年1月1日01:00:00 5-3=队列中的2辆2018年1月1日01:10:00 10-5=队列中的5辆车HI,谢谢你的帮助。但当两个列表的大小不一样时,我会遇到一些问题。此外,我还需要添加剩余车辆的累计数量。2018年1月1日00:00:00 12-3=9辆排队车辆2018年1月1日00:10:00 10-2=8辆排队车辆2018年1月1日01:00:00 5-3=2辆排队车辆2018年1月1日01:10:00 10-5=5辆排队车辆-更新了答案,为每个时隙添加了单独的队列大小tooHi,感谢您的帮助。但当两个列表的大小不一样时,我会遇到一些问题。此外,我还需要添加剩余车辆的累计数量。pastebin.com/print/RKA0FND8您在问题中没有描述任何这些要求。问一个新问题,包括适当的细节,并在问题中给出你想要的内容的示例输出(该链接不起作用)谢谢你的帮助,我一直在想你可以帮我开始,然后我自己试试。。这样我就不想被帮助。。但是,你们太棒了!!
    List<TimeslotQueue> queues = Streams.zip(vehicles.stream(), planning.stream(), 
         (v, p) -> new TimeslotQueue(v.getDate(), 
                        v.getNbOfVehicleArriving() - p.getNbOfallowedVehicles()))
         .collect(Collectors.toList());