假设我有一个列表List<Foo> mylist = parseFromCSV();
哪里
parseFromCSV()
返回Foo
类对象的列表。 Foo类有她的私人属性:
private mailId;
private status;
......吸气鬼和二传手......
中可能有一对物体
mylist: [{MailId=100, Status=BOUNCED, EMAIL=test@test.com},{MailId=100, Status=OPENED, EMAIL=test2@test.com}, {MailId=200, Status=CLICKED, EMAIL = test3@test.com}, {MailId=100, Status=HARDBOUNCED, EMAIL = test4@test.com}]
我的列表中确实可以有重复项,因为列出的对象表示解析为Java对象的CSV行。 每个MailId都有多种不同的反馈状态。
我感兴趣的是,只检索&#34; important&#34;状态在我的一组MailId的可能状态集中并持久存储到我的数据库中。
已打开&gt;点击&gt; HARDBOUNCED&gt; BOUNCED(状态的优先级)。
在我的示例中:对于MailId = 100,我只会将OPENED状态持久保存到数据库中的状态列中。
实现这一目标的好方法是什么?我应该创建一个新的List(Set?),其中包含已过滤{MailId, Status(Prioritized)}, ... {MailIdN, StatusN(Prioritized)...}
的每一对吗?我们可以使用Enumerations为String添加优先级,还是为Foo类的对象创建一个新的比较器?
使用hibernate对mysql数据库的持久操作应如下所示:
persistStatusIntoTable(String MailId, String Status(Taken only status based on priority))
感谢您的帮助!
答案 0 :(得分:2)
我在这里假设了几件事(可以很容易地改变)。首先Status
是枚举(例如,您可以对String
执行相同的操作)。
然后我使用google guava Ordering
来简化Comparator
的构建(如果没有它,你可以这样做)。
Comparator<Status> c = Ordering.explicit(
ImmutableList.of(Status.OPENED, Status.CLICKED, Status.HARDBOUNCED, Status.BOUNCED));
List<Foo> list = Stream.of(new Foo(Status.BOUNCED, 57), new Foo(Status.OPENED, 57),
new Foo(Status.CLICKED, 58), new Foo(Status.BOUNCED, 57),
new Foo(Status.HARDBOUNCED, 58))
.collect(Collectors.groupingBy(Foo::getId,
Collectors.mapping(Foo::getStatus, Collectors.toCollection(() -> new PriorityQueue<>(c)))))
.entrySet()
.stream()
.map(e -> new Foo(e.getValue().remove(), e.getKey()))
.collect(Collectors.toList());
System.out.println(list); // [id = 57 status = OPENED, id = 58 status = CLICKED]
我们的想法是创建一个Comparator
来定义Status
es的顺序;然后使用该比较器填充PriorityQueue
(对于某些id);最终我只对第一个感兴趣 - 你称之为重要(根据比较者的说法,这是第一个)。
以下是使用String
与enum
Status
的版本:
Comparator<String> c = Ordering.explicit(
ImmutableList.of("OPENED", "CLICKED", "HARDBOUNCED", "BOUNCED"));
List<Foo> list = Stream.of(new Foo("BOUNCED", 57), new Foo("OPENED", 57),
new Foo("CLICKED", 58), new Foo("BOUNCED", 57),
new Foo("HARDBOUNCED", 58))
.collect(Collectors.groupingBy(Foo::getId,
Collectors.mapping(Foo::getStatus, Collectors.toCollection(() -> new PriorityQueue<>(c)))))
.entrySet()
.stream()
.map(e -> new Foo(e.getValue().remove(), e.getKey()))
.collect(Collectors.toList());
答案 1 :(得分:2)
如果您不想使用第三方库而又不想使用枚举类:
// initialization which you will have to do once somewhere in your code
List<String> ordering = Arrays.asList("OPENED", "CLICKED", "HARDBOUNCED", "BOUNCED");
Map<String, Integer> priorityMap = IntStream.range(0, ordering.size()).boxed()
.collect(Collectors.toMap(ordering::get, i -> i));
// example input
List<Foo> myList = Arrays.asList(
new Foo("100", "BOUNCED"), new Foo("100", "OPENED"),
new Foo("101", "BOUNCED"), new Foo("101", "HARDBOUNCED"), new Foo("101", "BOUNCED"));
// determine foo objects that should be persisted
Collection<Foo> toBePersisted = myList.stream()
.filter(t -> priorityMap.containsKey(t.getStatus()))
.collect(Collectors.toMap(Foo::getMailId, t -> t,
BinaryOperator.minBy(Comparator.comparing(t -> priorityMap.get(t.getStatus())))))
.values();
此代码的作用是: