Java 8:带有 where 条件的 Lambda 表达式

Posted

技术标签:

【中文标题】Java 8:带有 where 条件的 Lambda 表达式【英文标题】:Java 8 : Lambda expression with where condition 【发布时间】:2020-10-06 00:59:33 【问题描述】:

假设我在 DB 的表中有以下记录。

这里 Emplid 和日期组合是我的 PK。 每次更改时,我都会维护记录的版本。 (在最后 3 行中,总共有 3 个版本作为数量变化)。

现在我想获取最新版本的记录 where emplid = 1111 date = 28-02-2019(用户不知道 db 中有多少个版本)。

如何使用 lambda 表达式来做到这一点。

HrcKey matchedKey = hrcKeyList.stream()
             .filter(x -> (currEmplid.equals(x.getEmplid()) && 
                     format.format(updateListFromUI.getDate())
                                  .equals(format.format(x.getDate()))))
             .findFirst()
             .orElse(null);

这会给我版本 1。 但是我怎样才能获得最新版本。

【问题讨论】:

findFirst()之前的版本排序 这能回答你的问题吗? How to use a Java8 lambda to sort a stream in reverse order? 不,实际上为了按版本排序,我需要 HrcRestatementKey 中不存在的版本字段(由用户提供)。 如果您的数据源是数据库,为什么不使用 SQL 并编写一个查询来返回您需要的数据? SQL 在这方面非常擅长。或者这纯粹是一个使用 Java 的流 API 的练习? 您的日期字段的类型是什么?为什么不对它们使用equals 而不是比较格式化字符串? 【参考方案1】:

您可以使用max 通过比较version 的值来获取最新的对象。

hrcRestatementKeyList.stream()
            .filter(x -> (currEmplid.equals(x.getEmplid()) &&
                    format.format(updatedHrcDbpRestatement.getExtr_effdt())
                            .equals(format.format(x.getExtr_effdt()))))
            .max(Comparator.comparingInt(HrcRestatementKey::getVersion))
            .orElse(null);

【讨论】:

【参考方案2】:

总之你可以做这样的事情,

employees.stream().
                filter(hrc -> hrc.empid == 11 && hrc.date.equals("28-02-2000")).
                min((o1, o2) -> o2.version - o1.version).orElse(null);

完整示例,

public static void main(String[] args) 
        RnD rnD = new RnD();
        rnD.test();
    
    private void test() 
        List<Hrc> employees = new ArrayList<>();
        employees.add(new Hrc(11, "28-02-2000", 1));
        employees.add(new Hrc(11, "28-02-2000", 2));
        employees.add(new Hrc(11, "28-02-2000", 3));
        employees.add(new Hrc(11, "30-02-2000", 1));
        employees.add(new Hrc(22, "11-02-2000", 1));
        Hrc topVersion= employees.stream().
                filter(hrc -> hrc.empid == 11 && hrc.date.equals("28-02-2000")).
                min((o1, o2) -> o2.version - o1.version).orElse(null);
        System.out.println(topVersion);
    
    private static class Hrc 
        int empid;
        String date;
        int version;

        public Hrc(int empid, String date, int version) 
            this.empid = empid;
            this.date = date;
            this.version = version;
        

        @Override
        public String toString() 
            return "Hrc" +
                    "empid=" + empid +
                    ", date='" + date + '\'' +
                    ", version=" + version +
                    '';
        
    

【讨论】:

不要依赖(o1, o2) -&gt; o2.version - o1.versioncompare!请参阅HadiJ's answer 以获得更好和正确的产品。【参考方案3】:

我会使用这个代码 sn-p:

yourList.stream()
        .filter(x -> currEmplid.equals(x.getEmplid())
        .filter(x -> updatedHrcDbpRestatement.getExtr_effdt()
                                             .equals(x.getExtr_effdt())
        .max(comparingInt(HrcRestatementKey::getVersion))
        .orElse(null);

【讨论】:

以上是关于Java 8:带有 where 条件的 Lambda 表达式的主要内容,如果未能解决你的问题,请参考以下文章

带有 Where 条件的 HSQLDB 问题

使用带有标量函数的 where 条件与使用交叉应用和表值函数的 where 条件

TRUNCATE TABLE 语句中可以带有where字句吗

带有 WHERE 条件和 INNER JOIN 的 SELECT 命令

带有 where 条件的 PL/SQL 更新查询作为带有一些空值的选择查询

如何在带有 jOOQ 的 WHERE 条件下使用 Postgres JSON 运算符?