使用流收集列表中最大的连续序列整数

时间:2015-11-20 18:23:24

标签: java java-8 java-stream

我有一个整数值列表,我想在列表中找到最大的连续序列整数。

例如,让L为以下整数列表:

  

L = {1,3,4,6,7,8,10,12,13}

然后我想从流中收集以下整数:

  

6,7,8

因为这些数字是列表L中最大的连续序列整数。

是否可以在Java 8中使用流来实现?

到目前为止,这是我在Java中使用简单迭代的方法:

    int maxSeqSize = 0;
    List<Cards> maxSeq;
    int currentNumber;
    int startSeq = -1;

    List<Card> currentCards = new ArrayList<> Cards.getCards());
    Collections.sort(currentCards, Cards::CompareByNumber);

    for (currentNumber = 0; currentNumber< Cards.getCards().size() - 1; currentNumber++){
           if((isSequentialCards(Cards.getCards().get(currentNumber ),
                                Cards.getCards().get(currentNumber + 1)))) {
            if (startSeq == -1) 
               startSeq = currentNumber ;

           }
           else {
             if(startSeq > 0 && currentNumber - startSeq + 1 >= maxSeqSize ) 
             {                                        
                  maxSeqSize = currentNumber - startSeq + 1;
                  maxSeq = currentCards .subList(startSeq,currentNumber +1);
             }
                    startSeq = -1;
           }
      }

      return maxSeq;

虽然isSequentialCards比较两张牌的价值:

private boolean isSequentialCards(Card c1, Card c2) {
    if((c1.getNumber() == c2.getNumber() - 1))
        return true;
    return false;
}

提前致谢

1 个答案:

答案 0 :(得分:1)

我能用流做的最好:

List<Card> largestSequence = cards.stream()
            //.sorted((card1, card2) -> card1.getNumber() - card2.getNumber())
            .collect(
                    (Supplier<List<List<Card>>>) ArrayList::new,
                    (sequences, currentCard) -> {
                        if (sequences.size() == 0 || !isSequentialCards(getLast(getLast(sequences)), currentCard)) {
                            sequences.add(new ArrayList<>());
                        }
                        getLast(sequences).add(currentCard);
                    },
                    List::addAll)
            .stream()
            .sorted((sequence1, sequence2) -> sequence2.size() - sequence1.size())
            .findFirst()
            .get();

步骤是什么:

  • 查找连续数字的所有序列
  • 从最大到最小的顺序
  • 获得第一个序列(最大的)

怎么样?

  • 排序:我评论过,因为我不知道您是否想要列表顺序中的最大序列,或者@ cr0ss建议。它基本上按升序对列表进行排序,最小的数字到最大。
  • 收集:您可以在其中看到三个&#34;操作&#34;收藏家可以提供(如Collectors.toList)。它找到了一系列连续数字的神奇之处。该实现尝试收集连续数字的序列列表(也是列表)。 :
    • 供应商:初始化容器:卡片列表列表(卡片序列列表)。
    • 累加器:使数字插入序列的原因(在下一部分中描述)。
    • combiner :定义如何合并两个列表。没用但需要,基本的addAll就足够了。
  • 排序:将序列从最大到最小排序
  • findFirst :取第一个,因此是最大的

我在another answer找到了关于收藏家的信息。其余的全部来自java文档。

什么使数字成为序列的一部分?

给出清单3,4,6 没有序列存在,创建一个新的序列。

[] -> [[]]

在最后一个序列的末尾插入3。

[[]] -> [[3]]

至少存在一个序列,4个连续到3,即最后一个序列的最后一个数字。 在最后一个序列的末尾插入4。

[[3]] -> [[3, 4]]

序列存在,但6不连续到4,即最后一个序列的最后一个数字。创建一个新序列。

[[3, 4]] -> [[3, 4], []]

在最后一个序列的末尾插入6。

[[3, 4], []] -> [[3, 4], [6]]

就像@Manos所说,流是解决这个问题的奇怪选择。我认为问题在于,当你不习惯流,lambda或收藏家时,很难维护,特别是像这里的单行(个人选择,我更喜欢我的代码是可维护的任何人)。