J'ai un cours de pojo comme celui ci-dessous

public CategoryModel {

public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

}

J'ai une arraylist créée comme celle ci-dessous.

List<CategoryModel> variantCategoryModelList = new ArrayList<>();
CategoryModel cat1= new CategoryModel();
cat1.setName(TEST1);
CategoryModel cat2= new CategoryModel();
cat2.setName(TEST1);
list.add(cat1);
list.add(cat2);

Je dois vérifier si la valeur "TEST1" et "TEST2" présente dans la liste et retourner "true" si les deux valeurs présentes dans la "liste" et j'ai essayé quelque chose comme celui ci-dessous, bien que ma "liste" ait à la fois le valeurs, il renvoie false.Pourriez-vous s'il vous plaît m'aider à vérifier ce que je fais de mal, car j'utilise JDK 11.

final Optional<CategoryModel> optionalData = variantCategoryModelList.stream().
                filter(valueData -> TEST1.equalsIgnoreCase(valueData.getName())
                        && TEST2.equalsIgnoreCase(valueData.getName())).findFirst();

        if(optionalData.isPresent()){
            return true;
        }
2
techy360 6 oct. 2020 à 14:38

3 réponses

Meilleure réponse

Set serait une structure de données plus naturelle (et plus rapide):

return variantCategoryModelList.stream()
                       .map(CategoryModel::getName)
                       .collect(Collectors.toSet())
                       .containsAll(Set.of("TEST1", "TEST2"));

Votre problème était et (&&) au lieu de ou .

Donc:

Set<String> soughtNames = Set.of("TEST1", "TEST2");
return variantCategoryModelList.stream()
                       .filter(cm -> soughtNames.contains(cm.getName()))
                       .distinct()
                       .count() == 2L;

Comme @fps l'a commenté, distinct() est nécessaire sur une liste pour éviter que ["Test1", "Test1"] ne soit accepté ou que ["Test1", "Test1", "Test2"] échoue. < / em>

Ceci est évidemment inefficace car il va - après avoir trouvé 2 entrées -, marcher toujours jusqu'au bout.

Tu veux:

Set<String> soughtNames = Set.of("TEST1", "TEST2");
return soughtNames.stream()
    .allMatch(soughtName ->
         variantCategoryModelList.stream()
             .anyMatch(cm -> soughtName.equals(cm.getName()));

Ou un peu rétro:

return
    variantCategoryModelList.stream()
             .anyMatch(cm -> "TEST1".equals(cm.getName())) &&
    variantCategoryModelList.stream()
             .anyMatch(cm -> "TEST2".equals(cm.getName()));
5
Joop Eggen 7 oct. 2020 à 07:11

Vous pouvez mapper votre CategoryModel au nom et collecter la liste de chaînes et appeler List.containsAll:

return variantCategoryModelList.stream()
                               .map(CategoryModel::getName)
                               .collect(Collectors.toList())
                               .containsAll(Arrays.asList("TEST1","TEST2"));
6
YCF_L 6 oct. 2020 à 12:00

Voici une façon de procéder:

Set<String> set = Set.of("TEST1", "TEST2");
boolean result = list.stream()
    .filter(cat -> set.contains(cat.getName().toUpperCase())
    .distinct()
    .limit(2)
    .count() == 2L;

Cela diffuse la liste des catégories, puis ne conserve que les catégories dont le nom est TEST1 ou TEST2. Nous supprimons ensuite les doublons et nous nous arrêtons après avoir trouvé deux noms de catégories (déjà distincts). Cela garantit un court-circuit . Enfin, nous vérifions si nous avons exactement deux éléments à la fin.

1
fps 8 oct. 2020 à 03:52