簡體   English   中英

使用 IntStream 而不是流迭代兩個列表列表

[英]Iterate over two Lists of Lists with IntStream instead of streams

我正在嘗試使用流來迭代兩個列表列表,以驗證同一索引的內部列表大小是否相同。 我設法使用流實現了這一點,但我必須使用IntStreammapToObj重寫。

我目前的做法是:

List<List<String>> a = config.getStrips();
List<List<Integer>> b = slotMachineConfig.getWeights();

a.stream()
 .filter(first ->
    b.stream()
     .allMatch(second -> second.size() == first.size())
 )
 .findFirst()
 .orElseThrow(InvalidConfigException::new);

問題是我不能確定大列表的大小是否對應,所以我必須使用 IntStream 重寫它,並為每個列表使用索引。

到目前為止我所擁有的但不起作用的看起來像這樣,我正在嘗試編寫一個“驗證”函數以驗證內部列表,但似乎我在那里收到錯誤消息“沒有類型變量 U 的實例存在所以空隙符合U”。

IntStream.range(0, a.size())
    .mapToObj(i -> validate(i, a.get(i), b.get(i)))
    .findFirst()
    .orElseThrow(SlotMachineInvalidConfigException::new);

public void validate(int index, List<String> firstList, List<Integer> secondList) {

如何使用IntStreammapToObj重寫我的方法,誰能幫助我?

如果我理解正確,我認為這樣的事情會起作用:

List<List<String>> a = config.getStrips();
List<List<Integer>> b = slotMachineConfig.getWeights();

if (a.size() != b.size()) throw new InvalidConfigException();
boolean allTheSame = IntStream.range(0, a.size())
    .map(i -> a.get(i).size() - b.get(i).size())
    .allMatch(diff -> diff == 0);
if (!allTheSame) throw new InvalidConfigException();

您的想法是正確的,但如果您只是比較大小,則實際上並不需要單獨的驗證功能。 這是一個支持任何列表類型的工作示例:

public class ListSizeMatcher {
    public <T,S> boolean  sizeMatches(List<List<T>> list1, List<List<S>> list2) {
        return list1.size() == list2.size()
                && IntStream.range(0, list1.size())
                    .allMatch(i -> list1.get(i).size() == list2.get(i).size());
    }
    public static void main(String[] args) {
        ListSizeMatcher matcher = new ListSizeMatcher();
        System.out.println(matcher.sizeMatches(List.of(List.of(1)), List.of(List.of("a"), List.of("b"))));
        System.out.println(matcher.sizeMatches(List.of(List.of(1)), List.of(List.of("a", "b"))));
        System.out.println(matcher.sizeMatches(List.of(List.of(1, 2)), List.of(List.of("a", "b"))));
    }
}

請注意,從設計角度來看,如果列表中的每個項目都與單獨列表中的相應項目相匹配,您最好創建一個包含這兩個項目的單個類。

作為記錄,您的驗證函數返回void但我假設它是為了返回一個布爾值

這是一個更緊湊的版本

               List<List<String>> a = new LinkedList<>();
        List<List<Integer>> b = new LinkedList<>();
        boolean match = IntStream.range(0, a.size())
                .mapToObj(i -> a.get(i).size() == b.get(i).size())
                .reduce(Boolean::logicalAnd).orElseThrow(InvalidConfigException::new);
        if (!match) {
            throw new InvalidConfigException();
        }

選擇:

     List<List<String>> a = new LinkedList<>();
        List<List<Integer>> b = new LinkedList<>();
        if (IntStream.range(0, a.size()).filter(i -> a.get(i).size() != b.get(i).size()).count() > 0){
            throw new InvalidConfigException();
        };

在一天結束時,只需要 1 次就可以不同並失敗。

該錯誤意味着validate方法不能為空,並且應該返回一些有效值(可能是布爾值)。

如果內部列表的大小應該相等才能有效,則檢查可能如下所示:

// assuming the sizes of outer lists are equal
boolean allSizesEqual = IntStream.range(0, a.size())
    .allMatch(i -> a.get(i).size() == b.get(i).size());
if (!allSizesEqual) {
    throw new InvalidConfigException("Not all sizes are valid");
}

如果需要查找檢測到差異的特定索引:

List<Integer> badIndexes = IntStream.range(0, a.size())
    .filter(i -> a.get(i).size() != b.get(i).size()) // IntStream
    .boxed() // Stream<Integer>
    .collect(Collectors.toList());

if (!badIndexes.isEmpty()) {
    throw new InvalidConfigException("Different indexes found: " + badIndexes);
}

或者可以修復validate方法以返回過濾器的適當值:

boolean allItemsValid = IntStream.range(0, a.size())
    .allMatch(i -> listsAreValid(a.get(i), b.get(i)));
if (!allItemsValid) {
    throw new InvalidConfigException("Not all entries are valid");
}

public boolean listsAreValid(List<String> innerA, List<Integer> innerB) {
// any advanced logic
    return innerA.size() == innerB.size();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM