【问题标题】:Filter objects with a common characteristic过滤具有共同特征的对象
【发布时间】:2021-03-28 14:19:02
【问题描述】:

我需要查找我的集合是否包含至少 5 个具有共同属性值的元素并返回这些元素。

我这样做:

cards.stream()
     .filter(card -> cards.stream()
                          .filter(card1 -> card.getSuit() == card1.getSuit()).count() >= CombinationConstant.CARD_COUNT)
     .collect(Collectors.toList());

您认为过滤另一个流是不好的做法吗?

【问题讨论】:

  • 我假设变量cards 的类型是扩展java.util.Collection 的某个类或接口。 Collection中每个元素的类型是什么?
  • 每个元素都是卡片类型,具有私有花色字段。适合是枚举。
  • 什么是常用变量?您是否在cards 中寻找至少五个具有相同Suit 的元素?
  • 是的,我需要至少五个具有相同套装的元素。

标签: java arrays java-stream


【解决方案1】:

你还没有发布minimal, reproducible example,所以我创建了一个我希望是相关的。我了解到您正在尝试使用stream API。

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

public class PlayCard {
    public enum Suit {
        CLUBS, DIAMONDS, HEARTS, SPADES
    }
    private Suit  suit;
    private int  value;

    public PlayCard(Suit suit, int value) {
        this.suit = suit;
        this.value = value;
    }

    public Suit getSuit() {
        return suit;
    }

    public static void main(String[] args) {
        List<PlayCard> cards = new ArrayList<>();
        Random randomSuit = new Random();
        Suit suit = null;
        for (int i = 0; i < 5; i++) {
            switch (randomSuit.nextInt(4)) {
                case 0:
                    suit = Suit.CLUBS;
                    break;
                case 1:
                    suit = Suit.DIAMONDS;
                    break;
                case 2:
                    suit = Suit.HEARTS;
                    break;
                case 3:
                    suit = Suit.SPADES;
                    break;
                case 4:
                    break;
                default:
                    suit = null;
            }
            if (suit != null) {
                cards.add(new PlayCard(suit, 0));
            }
        }
        Map<PlayCard.Suit, List<PlayCard>> map = cards.stream()
                                                      .collect(Collectors.groupingBy(card -> card.getSuit()));
        map.values()
           .stream()
           .filter(list -> list.size() == 5)
           .findAny()
           .ifPresentOrElse(list -> System.out.println("Found one."),
                            () -> System.out.println("Nothing found."));
    }
}

一些可能有用的资源。
Aggregate Operations Oracle 的 Java 教程中的课程。
Processing Data with Java SE 8 Streams, Part 1
Part 2: Processing Data with Java SE 8 Streams

【讨论】:

    【解决方案2】:

    我不知道它是否比您的实施有效。但这是其中一种方式:

    List<String> cards = List.of("a","b","aa","bb","cc");
    int CARD_COUNT = 3;
        
    Map<Integer, Long> counted = cards.stream()
        .collect(Collectors.groupingBy((String i)-> i.length() , Collectors.counting()));
    System.out.println("all counted: " + counted);
            
    Map<Integer, Long> result = counted.entrySet().stream()
        .filter(k -> counted.get(k.getKey()) >= CARD_COUNT)
        .collect(Collectors.toMap(x -> x.getKey(), x1 -> x1.getValue()));;
    System.out.println("filtered " + result);
    

    输出:

    all counted: {1=2, 2=3}
    filtered {2=3}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 2013-07-12
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      • 2020-11-19
      • 1970-01-01
      相关资源
      最近更新 更多