根据字符串的优先级减少对象列表
Reduction of List of Objects based on priority of String
假设我有一个列表List<Foo> mylist = parseFromCSV();
哪里
parseFromCSV()
returns Foo
class 的对象列表。 Foo class 有她的私有属性:
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 都有多个不同的可能状态反馈。
我感兴趣的是只检索我的一个 MailId 的一组可能状态中的 "important" 状态 并保存到我的数据库中。
OPENED > CLICKED > HARDBOUNCED > BOUNCED(状态的优先级)。
在我的示例中:对于 MailId= 100,我只会将 OPENED 状态保存到数据库中的状态列中。
实现此目标的好方法是什么?我应该创建一个新列表(集合吗?),其中包含每对过滤的 {MailId, Status(Prioritized)}, ... {MailIdN, StatusN(Prioritized)...}
?我们可以使用枚举或为我的 class Foo 的对象创建一个新的比较器来增加 String 的优先级吗?
使用 hibernate 对 mysql 数据库的持久化操作应该如下所示:
persistStatusIntoTable(String MailId, String Status(Taken only status based on priority))
感谢大家的帮助!
我在这里假设了几件事(可以很容易地改变)。首先 Status
是一个枚举(但是你可以对 String
做同样的事情)。
然后我使用 google 番石榴 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
与 Status
的 enum
的版本:
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());
如果您不想使用第 3 方库并且不想使用枚举 class:
// 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();
这段代码的作用是:
- 设置一个将状态映射到优先级的映射(较低的 int = 较高的优先级)
- 过滤掉状态无效的 Foo 实例
- 按 mailId 对 Foo 实例进行分组
- 保持每个组具有最小优先级整数(=最高优先级)的 Foo 实例
- 获取结果地图的值
假设我有一个列表List<Foo> mylist = parseFromCSV();
哪里
parseFromCSV()
returns Foo
class 的对象列表。 Foo class 有她的私有属性:
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 都有多个不同的可能状态反馈。
我感兴趣的是只检索我的一个 MailId 的一组可能状态中的 "important" 状态 并保存到我的数据库中。
OPENED > CLICKED > HARDBOUNCED > BOUNCED(状态的优先级)。
在我的示例中:对于 MailId= 100,我只会将 OPENED 状态保存到数据库中的状态列中。
实现此目标的好方法是什么?我应该创建一个新列表(集合吗?),其中包含每对过滤的 {MailId, Status(Prioritized)}, ... {MailIdN, StatusN(Prioritized)...}
?我们可以使用枚举或为我的 class Foo 的对象创建一个新的比较器来增加 String 的优先级吗?
使用 hibernate 对 mysql 数据库的持久化操作应该如下所示:
persistStatusIntoTable(String MailId, String Status(Taken only status based on priority))
感谢大家的帮助!
我在这里假设了几件事(可以很容易地改变)。首先 Status
是一个枚举(但是你可以对 String
做同样的事情)。
然后我使用 google 番石榴 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
与 Status
的 enum
的版本:
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());
如果您不想使用第 3 方库并且不想使用枚举 class:
// 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();
这段代码的作用是:
- 设置一个将状态映射到优先级的映射(较低的 int = 较高的优先级)
- 过滤掉状态无效的 Foo 实例
- 按 mailId 对 Foo 实例进行分组
- 保持每个组具有最小优先级整数(=最高优先级)的 Foo 实例
- 获取结果地图的值