我有2个这样的课程:
public class Seat extends Moviefiable {
private int number;
private Hall hall;
public Seat(int id, boolean active, int number, Hall hall) {
super(id, active);
this.number = number;
this.hall = hall;
}
public Seat() {this(-1, false, -1, null);}
public static Seat getById(int idSeat) throws SQLException {
Seat seat = SeatDAO.getById(idSeat);
return seat;
}
}
public class Ticket extends Moviefiable {
private Projection projection;
private Seat seat;
private LocalDateTime purchasingDate;
private User user;
public Ticket(int id, boolean active, Projection projection, Seat seat, LocalDateTime purchasingDate, User user) {
super(id, active);
this.projection = projection;
this.seat = seat;
this.purchasingDate = purchasingDate;
this.user = user;
}
public Ticket() {this(-1, false, null, null, null, null);}
现在,我需要创建两个或多个Tickets
,具体取决于loggedInUser
选择的票证数量。从我的JSP
页面上,我将得到如下内容:
String uri = request.getQueryString(); //uri looks like this: seats=2&seats=3
我想为两个Ticket
对象创建两个Seat
对象。在uri
字符串中,字符2和3是席位的主键。
想法是使用Java流执行拆分和创建对象。这是我到目前为止。
ArrayList<Ticket> newTicketsForSeats = Stream.of(uri.split("&"))
.map(s -> s.split("seats=")[1])
//.flatMap(Arrays::stream)
.mapToInt(Integer::valueOf)
.mapToObj(s -> {
try {
return new Ticket(-1, true, projection, SeatDAO.getById(s),
LocalDateTime.now(), loggedInUser);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
})
.collect(Collectors.toCollection(ArrayList::new));
当我进行测试时,像这样查看我得到的输出:
Stream.of(uri.split("&"))
.map(s -> s.split("seats=")[1])
.mapToInt(Integer::valueOf)
.forEach(System.out::println); //2 3
哪个很好。但是当我在上面运行代码时,我得到了:
java.lang.ArrayIndexOutOfBoundsException: 1
at servlets.ConfirmPurchaseServlet.lambda$0(ConfirmPurchaseServlet.java:62)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
projection
也是我获得的对象,这只是参考,它在Servlet中的其他位置。 loggedInUser
我从会议中获得。我是Java流的新手,任何其他解释都将是非常好的。
我知道map()
需要IntUnaryOperator
lambda表达式,类似这样:
s -> s * 10
我不知道如何从int(Seat的主键)“映射”到Seat
对象。
干杯。
您的主要问题是您试图将流输出分配给ArrayList
。 Collectors.toList()
返回无法预期是特定实现的List
。
所以要么这样做:
List<SomeClass> list = ...collect(Collectors.toList());
或此
ArrayList<SomeClass> list = ... collect(Collectors.toCollection(ArrayList::new));
以下内容应该可以使用,但是可能需要根据您的其他类进行一些调整。
ArrayList<Ticket> newTicketsForSeats = Stream.of(uri.split("&"))
.map(s -> s.split("seats="))
.flatMap(Arrays::stream)
.mapToInt(Integer::valueOf)
.mapToObj(s -> new Ticket(-1, true, projection, SeatDAO.getById(s),
LocalDateTime.now(), loggedInUser))
.collect(Collectors.toCollection(ArrayList::new));
这些都可能有效:
List<Ticket> newTicketsForSeats = Stream.of(uri.split("&"))
.map(s -> s.replace("seats=", ""))
.mapToInt(Integer::valueOf)
.mapToObj(s -> new Ticket(-1, true, projection, SeatDAO.getById(s), LocalDateTime.now(), loggedInUser))
.collect(Collectors.toList());
或
List<Ticket> newTicketsForSeats = Stream.of(uri.split("&"))
.map(s -> s.replace("seats=", ""))
.map(s -> new Ticket(-1, true, projection, SeatDAO.getById(Integer.valueOf(s)), LocalDateTime.now(), loggedInUser))
.collect(Collectors.toList());
BTW:您似乎没有与签名匹配的Ticket构造函数:
Ticket(int, boolean, Projection, Seat, LocalDateTime, boolean)
我在解释问题时犯了一个错误。
我的原始字符串uri
为
String uri = request.getQueryString(); //seats=2&seats=3
这是错误的。我的实际字符串看起来像这样
//projection=1&seats=2&seats=3
我忘记了我要发送选定电影放映的主键,白痴。
现在,我设法获得了期望的结果:
ArrayList<Ticket> newTicketsForSeats =
Stream.of( String.join("", Arrays.copyOfRange(uri.split("&"), 1, uri.split("&").length)))
.map(s -> s.split("seats="))
.flatMap(Arrays::stream)
.filter(x -> !x.contentEquals(""))
.mapToInt(Integer::valueOf)
.mapToObj(s -> {
try {
return new Ticket(-1, true, projection, SeatDAO.getById(s),
LocalDateTime.now(), loggedInUser);
} catch (SQLException e) { e.printStackTrace(); return null;}
})
.collect(Collectors.toCollection(ArrayList::new));
Tho,我不喜欢Arrays.copyOfRange()
,据我所知,它太宽泛了。也许有机会解决这个问题?