[英]Spliting string, flatMapping it and creating objects using Java streams?
我有 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
我想為兩個Seat
對象創建兩個Ticket
對象。 在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());
順便說一句:您似乎沒有與簽名匹配的票證構造函數:
Ticket(int, boolean, Projection, Seat, LocalDateTime, boolean)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.