Quarkus Mutiny:Multi转Uni返回null问题求助
问题分析:Multi转Uni实现员工添加逻辑的错误
我开发了一个响应式程序,需求是当ArrayList中不存在相同ID的员工时,将新员工添加到列表中。但使用以下Multi转Uni的代码时,即使ArrayList为空(不可能存在重复ID),仍返回null。我已通过另一段基于Uni实现的代码达成需求,但认为前者写法更优,想请教代码中的错误之处:
第一段问题代码
public Uni<Employee> addEmployeee(Employee employee){ return Multi.createFrom().iterable(employees) .onItem().transform(empl -> { if(empl.getId().equals(employee.getId())){ return null; }else { employees.add(employee) ; } return employee ; }).toUni() ; }
第二段可行代码
public Uni<Employee> addEmployee(Employee employeeToAdd){ return Uni.createFrom().item(employees) .onItem().transform(employees ->{ Optional<Employee> exists = employees.stream().filter(empl -> empl.getId().equals(employeeToAdd.getId())).findFirst(); if(exists.isEmpty()){ employees.add(employeeToAdd); return employeeToAdd; } return null; }); }
第一段代码的核心错误
1. 空列表场景直接返回null
当employees为空时,Multi.createFrom().iterable(employees)会生成一个无元素的Multi。调用toUni()方法时,若Multi没有任何元素,Mutiny会直接返回一个包含null的Uni,这就是空列表时返回null的根本原因。
2. 遍历逻辑完全偏离需求
就算列表不为空,这段代码的逻辑也存在致命问题:
- 遍历列表中的每一个员工,只要当前员工ID和新员工不匹配,就执行
employees.add(employee),这会导致新员工被重复添加N次(N为列表中不匹配的员工数量)。 - 如果找到ID匹配的员工,返回null,但此时前面已经可能多次添加过新员工了,完全违背了"不存在重复ID才添加"的需求。
transform操作的设计目的是转换元素,不是用来执行修改列表这类副作用操作,这种写法不符合响应式编程规范,还可能引发线程安全问题。
正确的Multi实现方式
如果想用Multi实现需求,应该先检查是否存在重复ID,再决定是否添加:
public Uni<Employee> addEmployee(Employee employee) { return Multi.createFrom().iterable(employees) // 过滤出ID匹配的员工 .filter(empl -> empl.getId().equals(employee.getId())) // 检查是否存在匹配元素 .hasElements() .onItem().transform(hasDuplicate -> { if (!hasDuplicate) { employees.add(employee); return employee; } return null; }); }
内容的提问来源于stack exchange,提问作者Xlorokoptiko Gia Gkazon
相关产品推荐
相关产品推荐

