如何获取 Java Stream 中每种类型(按属性选择)的第一个对象(按函数排序)

2023-12-01

想象一个具有 3 个属性的简单对象:

public class Obj {

    boolean toBeAdded;
    String type;
    int order;

    public Obj(boolean toBeAdded, String type, int order) {
        this.toBeAdded = toBeAdded;
        this.type = type;
        this.order = order;
    }

    public boolean isToBeAdded() {
        return toBeAdded;
    }

    public String getType() {
        return type;
    }

    public int getOrder() {
        return order;
    }

}

想象一下我有一个包含几个的列表Objs,具有不同类型:

import java.util.Arrays;
import java.util.List;

public class Utils {

    static List<Obj> createA(){
        List<Obj> list = Arrays.asList(
                new Obj(true, "A", 1),
                new Obj(false, "A", 2),
                new Obj(true, "A", 3),
                new Obj(false, "A", 4)
        );
        return list;
    }


    static List<Obj> createB(){
        List<Obj> list = Arrays.asList(
                new Obj(true, "B", 1),
                new Obj(false, "B", 2),
                new Obj(true, "B", 3),
                new Obj(false, "B", 4)
        );
        return list;
    }


    static List<Obj> createC(){
        List<Obj> list = Arrays.asList(
                new Obj(false, "C", 1),
                new Obj(false, "C", 2),
                new Obj(true, "C", 3),
                new Obj(true, "C", 4)
        );
        return list;
    }
}

我想以某种方式过滤这个列表并获得最新的Obj(最高order值)对于每个type可以添加(toBeAdded = true).

对于此示例,结果应该是一个包含以下内容的列表:

  • Obj1:类型 1,顺序 3
  • Obj2:类型 2,顺序 3
  • Obj3:类型 3,顺序 4

我知道如何过滤和如何排序,但我仍然不明白如何获得每个子类型中的第一个。这是否反对Stream规则?因为我想做的基本上是解析N个不同的子流,对于N个不同的子流types?

到目前为止我可以做的是:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class MainTest {

    public static void main(String[] args) {

        List<Obj> list = new ArrayList<>();
        list.addAll(Utils.createA());
        list.addAll(Utils.createB());
        list.addAll(Utils.createC());

        System.out.println(list);

        List<Obj> filteredList = list
                .stream()
                .filter(Obj::isToBeAdded)
                .sorted(Comparator.comparingInt(Obj::getOrder).reversed())
                .collect(Collectors.toList());

        System.out.println(filteredList);

    }


}

然而,这只是完成简单的部分——过滤和排序。我仍然需要做类似的事情findFirst()对于每个type。有什么办法可以做到这一点吗?

我是否必须执行 3 个不同的流(每种类型一个),然后合并列表?有没有办法在不知道我们将有多少类型的情况下做到这一点? 我还读到collect(Collectors.groupingBy())但这会为每种类型创建不同的地图,这是我不想要的。


Using groupingBy可以与下游一起提供帮助minBy/maxBy。这将提供一个映射来查找过滤后的值是否存在于每种类型中。

Map<String, Optional<Obj>> groupMaxOrderByType = list.stream()
        .filter(Obj::isToBeAdded)
        .collect(Collectors.groupingBy(Obj::getType,
                Collectors.maxBy(Comparator.comparingInt(Obj::getOrder)))); //highest order

对这些对象的查找或访问将转换为如下内容:

Obj maxPerTypeA = groupMaxOrderByType.get("A").orElse.. // similar for each type

Edit:或者,如果您要将所有此类现有类型收集到最终结果中,您可以按照以下步骤访问Map.

List<Obj> result = groupMaxOrderByType.values().stream()
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());

Edit:或者摆脱处理Optional, 您可以使用toMap with BinaryOperator.maxBy作为合并函数。

Map<String, Obj> groupMaxOrderByType = list.stream()
        .filter(Obj::isToBeAdded)
        .collect(Collectors.toMap(Obj::getType, Function.identity(), 
                BinaryOperator.maxBy(Comparator.comparingInt(Obj::getOrder))));
List<Obj> result = new ArrayList<>(groupMaxOrderByType.values());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何获取 Java Stream 中每种类型(按属性选择)的第一个对象(按函数排序) 的相关文章

  • Java EE:如何获取我的应用程序的 URL?

    在 Java EE 中 如何动态检索应用程序的完整 URL 例如 如果 URL 是 localhost 8080 myapplication 我想要一个可以简单地将其作为字符串或其他形式返回给我的方法 我正在运行 GlassFish 作为应
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • 删除近排序数组中未排序/离群元素

    给定一个像这样的数组 15 14 12 3 10 4 2 1 我如何确定哪些元素乱序并删除它们 在本例中为数字 3 我不想对列表进行排序 而是检测异常值并将其删除 另一个例子 13 12 4 9 8 6 7 3 2 我希望能够删除 4 和
  • 从 Laravel 4 输入生成新数组

    我使用 Input all 从动态生成的表单中获取一些输入 我使用 jQuery 来允许用户添加字段 字段名称为 first names last names 和 emails input 变量现在看起来像这样 array size 4 t
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 在 HTML 下拉列表中有一个滚动条

    我正在寻找一种在 HTML 的下拉列表中添加滚动条的方法 这样如果下拉列表包含的内容超过例如 5 项 将出现滚动条以查看其余项 这是因为我将被迫列出一些大清单 过去几个小时我一直在谷歌上搜索它 但没有运气 它需要适用于 IE8 FF 和 C

随机推荐