【问题标题】:Find (custom) objects in list from another list从另一个列表中查找(自定义)列表中的对象
【发布时间】:2020-06-14 04:35:48
【问题描述】:

我有两个列表(火车、货车)。我只想拥有来自“wagon”列表的货车并将它们存储在“finalList”中。

List<train> trains;
List<wagon> wagons;

List<train> finalList

火车具有属性 ID、颜色、货车。 货车具有属性 ID、座位、类型。 两个列表都有几个条目。

List<train> finalList= trains.stream().filter(tr-> tr.getWagons.retainAll(wagons)).collect(Collectors.toList());

我的 finalList 每次都是空的,我不知道为什么。与 containsAll() 相同。 我也尝试过类似的方法:

finalList = trains.stream().filter(tr -> wagons.stream().anyMatch(wg -> tr.getWagons().foreach(trWg -> trWg.getId().equals(wg.getId()))))

但我无法从货车列表中按货车过滤火车列表

【问题讨论】:

  • 你不想.isEmpty()吗? containsAll 意味着火车有所有的货车。 retainAll 应该可以工作(尽管修改!) - 是否有一个狡猾的 equals 方法?
  • 不,我想过滤火车列表,以便从货车列表中获得所有带货车的火车。但我没有得到匹配的条目
  • 哦,我明白了。 .getWagons. 是一种方法(复制List 的方法)? finalList 为空意味着 retainAll 返回 false,即没有修改。即使是没有货车的火车?否则我会期望 equals 方法总是返回 false
  • 请为每个人发布 POJO。
  • 请注意,列表中的wagontrain 的属性可能是不同的实例(不同的@)。这完全取决于这两个货车是如何被实例化的,如果列表中充满了来自火车的货车,那么您可以比较两个对象,否则您应该实现自己的比较器方法。

标签: java arraylist filter java-8 java-stream


【解决方案1】:

我不知道你的 POJO 是什么,因为你没有发布它们,所以我所能做的就是从你发布的 属性 列表中假设。这是一种方法。

我们所做的只是循环遍历所有火车,并根据 Wagon 对象列表中是否包含与火车上的货车具有相同 id 的货车进行过滤。然后我们收集到一个列表。

    List<Train> trains = Arrays.asList(
            new Train(1, 0, new Wagon(0, 1, 0)), 
            new Train(2, 0, new Wagon(1, 1, 0)));

    List<Wagon> wagons = Arrays.asList(new Wagon(0, 1, 0));

    List<Train> trainsFromWagons = trains.stream().filter(train -> wagons.stream().anyMatch(wagon -> train.wagon.id == wagon.id))
            .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    所以首先在描述中你说的是

    火车具有属性 ID、颜色、Wagon

    但是,在后面的例子中:

    finalList = trains.stream() .filter(tr -> wagons.stream() .anyMatch(wg ->tr.getWagons() .foreach(trWg -> trWg.getId().equals(wg.getId()))));

    因此我假设第一个是真的,出于某种原因你的火车现在只能有一辆货车

    这个“问题”有几种解决方案:

    我认为第一个也是最干净的方法:

    List<Wagon> wagons = new ArrayList<>();
    
        wagons.add(new Wagon(0L, new ArrayList<>(), "0"));
        wagons.add(new Wagon(1L, new ArrayList<>(), "1"));
    
        List<Train> trains = new ArrayList<>();
    
        trains.add(new Train(0L, wagons.get(0), "Yellow"));
        trains.add(new Train(1L, wagons.get(1), "Blue"));
        trains.add(new Train(2L, new Wagon(12L, new ArrayList<>(), "not in wagon list"), "Blue"));
    
    
        List<Train> finalList = trains.stream().
                filter(train -> wagons.contains(train.getWagon()))
                .collect(Collectors.toList());
    
        finalList.forEach(System.out::println);
    

    和ofc POJO的

    @Getter
    @AllArgsConstructor
    @ToString
    class Train {
        private Long id;
        private Wagon wagon;
        private String color;
    }
    
    @Getter
    @ToString
    @AllArgsConstructor
    @EqualsAndHashCode
    class Wagon {
        private Long id;
        private List<String> seats;
        private String type;
    }
    

    但你必须记住这里实现equals()Wagon

    无需实现equals()的第二种方法是:

      List<Train> finalList2 = trains.stream()
                .filter(train -> wagons
                        .stream()
                        .anyMatch(wagon -> wagon.getId().equals(train.getWagon().getId())))
                .collect(Collectors.toList());
    

    现在假设您的火车可以有不止一辆货车...

    @Getter
    @AllArgsConstructor
    @ToString
    class Train {
        private Long id;
        private List<Wagon> wagons;
        private String color;
    }
    

    还有代码:

    List<Wagon> wagons = new ArrayList<>();
    
    wagons.add(new Wagon(0L, new ArrayList<>(), "0"));
    wagons.add(new Wagon(1L, new ArrayList<>(), "1"));
    List<Wagon> wagons2 = new ArrayList<>();
    
    wagons2.add(new Wagon(11L, new ArrayList<>(), "11"));
    wagons2.add(new Wagon(12L, new ArrayList<>(), "12"));
    
    List<Train> trains = new ArrayList<>();
    
    trains.add(new Train(0L, wagons,"Yellow"));
    trains.add(new Train(1L, wagons2, "Blue"));
    trains.add(new Train(2L, Arrays.asList(new Wagon(132L, new ArrayList<>(),"not in wagon list")), "Blue"));
    
       List<Train> finalList3 = trains.stream()
                .filter(train -> train.getWagons().containsAll(wagons))
                .collect(Collectors.toList());
    
        finalList3.forEach(System.out::println);
    

    只要您假设,您只对包含精确货车组的火车感兴趣。而equals()也是这个方法所必需的!

    【讨论】:

      猜你喜欢
      • 2016-11-08
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 2016-11-18
      • 1970-01-01
      • 1970-01-01
      • 2011-11-26
      相关资源
      最近更新 更多