我需要写一个daymanagerr,为餐厅的订单分配时间段。
那是日间经理:
public DayManager (LocalDate date, int numberOfTimeSlots, int capacityPerSlot) {
this.date = date;
this.capacityPerSlot = capacityPerSlot;
this.numberOfTimeSlots = numberOfTimeSlots;
对于每一天,我可以选择可用插槽的数量和每个插槽的容量(因此,如果我选择3个插槽,每个插槽的容量为3,那么总共是9个插槽)。
每一个客户都可以在他们的订单中说明他们喜欢的时间段(这里是0、1或2)。
下面是我添加订单的类:
public Optional<Integer> addOrder(Order order, int preferredSlot) {
int givenSlot = 0, count = 1;
List<Integer> slots = new ArrayList<Integer>();
List<Integer> slotsPerSlot = new ArrayList<Integer>();
if ((slots.size() * slotsPerSlot.size()) <= (numberOfTimeSlots * capacityPerSlot)) {
if (slots.contains(preferredSlot) == false) {
givenSlot = preferredSlot;
slots.add(preferredSlot);
slotsPerSlot.add(count);
count++;
} else if (slotsPerSlot.size() <= capacityPerSlot) {
givenSlot = preferredSlot;
slots.add(preferredSlot);
slotsPerSlot.add(slotsPerSlot.size() + 1);
} else {
givenSlot = slots.get(slots.lastIndexOf(count));
}
return Optional.of(givenSlot);
}
return Optional.empty();
}
我需要帮助的是:
每一个新的订单,我都需要检查是否还有剩余的容量在客户首选的插槽。如果还有空位,我就把那个空位分配给他。如果该插槽中没有剩余的容量,我将为该插槽分配下一个最低的索引(和可用容量)。如果那天没有剩余的容量,我干脆什么也不回。
我只是不知道如何为每个插槽创建一个slotsPerSlot列表,另外我也不知道如何获得下一个最低的插槽号。
你可以用多地图。映射
是指向值键对。在multimap中,值实际上是值的集合,而不是单个值。
例如,想象一个由三个时隙组成的层次结构,其中第一个和最后一个时隙包含一个空列表(还没有订单),而中间时隙包含一个单订单的列表。
(小细节:2D8E5CC2-26AC-474D-A081-2C71207FD6C5
文本是用于标识特定顺序的128位UUID值的十六进制字符串表示形式。)
下面是一些示例代码。这段代码是不完整的,但将使您朝着正确的方向前进。
首先,定义我们的order
类。我们将使它成为一个记录,使用新的功能在Java 16。你可以定义一个常规的类,但是一个记录要简单得多。编译器隐式创建构造函数、getters、equals
&hashcode
和toString
。
package work.basil.example.orders;
import java.util.UUID;
public record Order(UUID id , String customerName)
{
}
定义DayManager
类。
构造函数是为跟踪订单设置数据结构的地方。您是在addOrder
方法中完成这项工作的,这是没有意义的。
构造函数的目标是填充一个navigableMap
,一个map
以排序的顺序维护其键。我们使用TreeMap
作为NavigableMap
接口的具体实现。
映射的关键字是zoneddatetime
,这是一个在时区上下文中具有time-of-day的日期。每个zoneddatetime
对象是每个时隙的开始。我使用这种方法,而不是仅仅使用整数来标识每个插槽。
映射的值是order
对象的列表。当我们将订单添加到我们的跟踪系统中时,它们就会出现在其中一个列表中。每个列表都绑定到一个zoneddatetime
对象,作为映射中的时隙。使用list
的问题在于类是一个可调整大小的集合。因此,这里的代码管理大小限制,检查当前大小以获得列表中已有多少订单的计数。我们将该计数与作为DayManager
类的成员字段保留的每时隙容量数进行比较。
optional
,其中包含ZonedDateTime
以标识时隙。ZonedDateTime
,用于访问映射的当前密钥。因此,如果我们添加存储为成员字段的duration
,我们将获得映射中的下一个键。使用该键获取下一个订单列表。起泡,冲洗,重复,直到一天中的最后一个时间段。顺便说一下,在实际工作中,我会使用第三方库(如Eclipse Collections或Google Guava)来获取固定大小的列表类。与其依赖我们这里的大小检查代码,不如依赖已经编写和测试过的代码。
我们在构造函数中用时隙和空列表预填充我们的映射。所以我们在开始添加订单时就有了一个数据结构。
addOrder
方法在映射中查找所请求的时隙作为键。在映射上执行get
将返回一个订单的list
以供我们检查。
package work.basil.example.orders;
import java.time.*;
import java.util.*;
public class DayManager
{
// Member fields.
final ZoneId zoneId;
final LocalDate workDate;
final LocalTime startTime;
final Duration timeSlice;
final int numberOfTimeSlots, capacityPerTimeSlot;
private final NavigableMap < ZonedDateTime, List < Order > > ordersPerTimeSlot;
// Constructor
public DayManager ( final ZoneId zoneId , final LocalDate localDate , final LocalTime startTime , final Duration timeSlice , final int numberOfTimeSlots , final int capacityPerSlot )
{
this.zoneId = zoneId;
this.workDate = localDate;
this.startTime = startTime;
this.timeSlice = timeSlice;
this.numberOfTimeSlots = numberOfTimeSlots;
this.capacityPerTimeSlot = capacityPerSlot;
this.ordersPerTimeSlot = new TreeMap <>();
this.populateMap();
}
// Subroutine.
private void populateMap ( )
{
ZonedDateTime start = ZonedDateTime.of( this.workDate , this.startTime , this.zoneId );
for ( int i = 0 ; i < this.numberOfTimeSlots ; i++ )
{
Duration d = this.timeSlice.multipliedBy( i );
ZonedDateTime zdt = start.plus( d );
List < Order > list = new ArrayList <>( this.capacityPerTimeSlot );
this.ordersPerTimeSlot.put( zdt , list );
}
System.out.println( "this.ordersPerTimeSlot = " + this.ordersPerTimeSlot );
}
// Business logic.
public Optional < ZonedDateTime > addOrder ( final Order order , final ZonedDateTime zdt )
{
List < Order > orders = this.ordersPerTimeSlot.get( zdt );
if ( Objects.isNull( orders ) ) { return Optional.empty(); }
if ( orders.size() > this.capacityPerTimeSlot )
{
String msg = "ERROR - Capacity per time slot exceeded. ";
System.out.println( msg );
throw new IllegalStateException( msg );
} else if ( orders.size() == this.capacityPerTimeSlot )
{
String msg = "INFO - This time slot filled.";
System.out.println( msg );
throw new IllegalStateException( msg );
} else if ( orders.size() < this.capacityPerTimeSlot )
{
// Room in this time slot to place order.
orders.add( order );
return Optional.of( zdt );
} else
{
String msg = "ERROR - Should never reach this point. Error in IF-THEN logic of adding orders.";
System.out.println( msg );
throw new IllegalStateException( msg );
}
}
// Debugging
public String dumpOrders ( )
{
return this.ordersPerTimeSlot.toString();
}
}
下面是一个app
类,用于执行我们的DayManager
&Order
类。
package work.basil.example.orders;
import java.time.*;
import java.util.Optional;
import java.util.UUID;
public class App
{
public static void main ( String[] args )
{
ZoneId z = ZoneId.of( "America/Edmonton" );
LocalDate ld = LocalDate.of( 2022 , Month.JANUARY , 23 );
DayManager dm = new DayManager( z , ld , LocalTime.of( 13 , 0 ) , Duration.ofHours( 1 ) , 3 , 3 );
Order order = new Order( UUID.fromString( "2d8e5cc2-26ac-474d-a081-2c71207fd6c5" ) , "Basil" );
Optional < ZonedDateTime > optionalTimeSlot = dm.addOrder( order , ZonedDateTime.of( ld , LocalTime.of( 14 , 0 ) , z ) );
System.out.println( "order = " + order );
System.out.println( "optionalTimeSlot.toString() = " + optionalTimeSlot );
System.out.println( dm.dumpOrders() );
}
}
运行时。
this.ordersPerTimeSlot = {2022-01-23T13:00-07:00[America/Edmonton]=[], 2022-01-23T14:00-07:00[America/Edmonton]=[], 2022-01-23T15:00-07:00[America/Edmonton]=[]}
order = Order[id=2d8e5cc2-26ac-474d-a081-2c71207fd6c5, customerName=Basil]
optionalTimeSlot.toString() = Optional[2022-01-23T14:00-07:00[America/Edmonton]]
{2022-01-23T13:00-07:00[America/Edmonton]=[], 2022-01-23T14:00-07:00[America/Edmonton]=[Order[id=2d8e5cc2-26ac-474d-a081-2c71207fd6c5, customerName=Basil]], 2022-01-23T15:00-07:00[America/Edmonton]=[]}
对于我的任务,我需要创建一个订单系统,该系统根据空闲容量分配时隙。我可以选择插槽数和每个插槽的容量(因此,如果我有3个插槽,每个插槽有3个容量,那么总共是9个插槽)。 每个客户在订单中说明他们的首选时隙(这里是0、1或2)。 我需要检查是否还有剩余的容量在他们想要的插槽,然后我才能下订单。如果有剩余的容量,我分配他们的首选插槽。如果没有剩余的容量,我会给他们分配一个下一个最低索引的插槽给他们的首选
问题内容: 我想要创建一个arraylist数组,如下所示: 但是它没有编译。我怎样才能做到这一点? 问题答案: 根据Oracle文档: “你不能创建参数化类型的数组” 相反,你可以执行以下操作: 正如汤姆·霍廷(Tom Hawting)的建议-定位线一样,最好这样做:
问题内容: 我有以下代码片段,我不明白为什么它不起作用: 有人能指出我正确的方向吗? 我已经看到JonSkeet在另一个问题上的回答,但是那里的最后一个示例对我来说不起作用。即使我将强制类型转换添加到标记为的行或行中,也会出现编译错误。 问题答案: 您始终可以通过明确指定type参数来告诉Java您想要列表:
问题内容: 我正在使用PHP。 我有以下具有关系数据(父子关系)的数组。 我需要采用这种JSON格式: 我知道我需要创建一个多维数组并通过json_encode()运行它。我还认为,用于此操作的此方法必须是递归的,因为现实世界中的数据可能具有未知数量的级别。 我很高兴展示我的一些方法,但是它们没有用。 谁能帮我? 我被要求分享我的工作。这是我尝试过的方法,但还没有达到我所不知道的帮助程度。 我做了
如何创建一个列表,其中的值介于我输入的两个值之间?例如,为11到16之间的值生成以下列表:
问题内容: 我想创建一个numpy数组,其中每个元素必须是一个列表,因此以后我可以向每个元素追加新元素。 我已经看过谷歌,这里已经有堆栈溢出,但是似乎找不到地方。 主要问题是numpy假定您的列表必须成为数组,但这不是我要的。 问题答案: 如您所见,在给出类似以下内容时,尝试创建2d数组 您已应用了一些技巧来解决此默认行为。 一种是使子列表的长度可变。它不能从这些数组中生成2d数组,因此它求助于对