【问题标题】:Splitting a List by multiple conditions按多个条件拆分列表
【发布时间】:2015-08-17 15:20:07
【问题描述】:

使用休眠我从示例表ANIMALS 中获取结果列表。 hibernate 方法如下所示:

...
List<Animals> animalList= null;
        try {
            Query query = session.createQuery("SELECT * FROM animals ORDER BY COLOR , HEIGHT , AGRESSIVE; ");
            animalList= query.list();
        }
...

结果集的示例如下:

NAME    COLOR   HEIGHT  AGRESSIVE
---------------------------------
JIMMY   BLACK   SHORT   NO
RIPPER  BLACK   SHORT   YES
GOOFY   BLACK   TALL    NO
MURPHY  BLACK   TALL    YES
PAUL    WHITE   SHORT   NO
ROB     WHITE   SHORT   YES
BOBBY   WHITE   TALL    NO
JACK    WHITE   TALL    YES

我的实际结果列表至少有 100,000 条记录,因此解析列表并为每个记录执行 list.add(..) 不是很明智; 我想要做的是将结果集拆分为 8 个较小的列表,其中包含COLORHEIGHTAGGRESSIVE 的每个组合。 之后,列表将作为参数提供给方法以执行一系列操作。

我只能使用 Java 1.6 或更低版本。 我的主要目标是摆脱我采取的IndexOutOfBounds 措施和IF's 的疯狂数量,如下所示:

    for (int i = 0; i < animalList.size(); i++) {
previousAnimal = animals.get(i-1);
currentAnimal = animals.get(i);
nextAnimal = animals.get(i+1);
    ...//extra code
    IF ( previousAnimal.getColor() != currentAnimal.getColor() || previousAnimal.getHeight() != currentAnimal.getColor() || previousAnimal.getAgressive() != currentAnimal.getAgressive() )
    ...//extra code
    IF ( currentAnimal.getColor() != nextAnimal.getColor() || currentAnimal.getHeight() != nextAnimal.getColor() || currentAnimal.getAgressive() != nextAnimal.getAgressive() )
    ...//extra code

【问题讨论】:

  • 如果您使用的是 Java 8,则可以使用 Stream API。如果您使用的是 Java 7 或更早版本,请使用 quaere 或类似的库
  • 过滤查询,可以使用Criteria of Criteria API
  • 或将所有内容放在MultiMap 中,并使用一致的hascode() 方法作为属性元组的键。
  • 您是否对整个数据集感兴趣,并且希望在 SQL 查询之后将其过滤到不同的数据结构中,或者您是否想要基于某些数据从您获得的 1,000,000 条记录中选择一个小数据集标准?
  • @ɐuıɥɔɐɯ 结果在 SQL 或 JAVA 中拆分都没有关系。我只对最快的解决方案感兴趣。我无法在某个属性之后在查询中进行过滤,因为随着时间的推移,这些属性可能会变成蓝色和红色而不是黑色和白色左右......

标签: java sql oracle hibernate


【解决方案1】:

或许您可以使用DENSE_RANK 分析函数来识别具有相似特征的动物:

...
List<Animals> animalList= null;
        try {
            Query query = session.createQuery("SELECT a.*, DENSE_RANK() OVER (ORDER BY COLOR, HEIGHT, AGRESSIVE) GRP FROM animals a ORDER BY COLOR, HEIGHT, AGRESSIVE; ");
            animalList= query.list();
        }
...

结果集的示例如下:

NAME    COLOR   HEIGHT  AGRESSIVE GRP
-------------------------------------
JIMMY   BLACK   SHORT   NO          1
RIPPER  BLACK   SHORT   YES         2
GOOFY   BLACK   TALL    NO          3
MURPHY  BLACK   TALL    YES         4
PAUL    WHITE   SHORT   NO          5
ROB     WHITE   SHORT   YES         6
BOBBY   WHITE   TALL    NO          7
JACK    WHITE   TALL    YES         8

ColorHeightAggressive 的每个不同组合都会为 GRP 列产生不同的值。然后你可以简化你的其他代码:

for (int i = 0; i < animalList.size(); i++) {
previousAnimal = animals.get(i-1);
currentAnimal = animals.get(i);
nextAnimal = animals.get(i+1);
    ...//extra code
    IF ( previousAnimal.getGrp() != currentAnimal.getGrp() )
    ...//extra code
    IF ( currentAnimal.getGrp() != nextAnimal.getGrp() )
    ...//extra code

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-16
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    • 2021-09-01
    • 2014-07-29
    相关资源
    最近更新 更多