英文:
Check if an arraylist contains two strings
问题
我有一个类似下面的POJO类
public class CategoryModel {
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
我创建了一个类似下面的ArrayList
List<CategoryModel> variantCategoryModelList = new ArrayList<>();
CategoryModel cat1 = new CategoryModel();
cat1.setName(TEST1);
CategoryModel cat2 = new CategoryModel();
cat2.setName(TEST1);
variantCategoryModelList.add(cat1);
variantCategoryModelList.add(cat2);
我需要检查列表中是否存在值"TEST1"和"TEST2",如果这两个值都在列表中,则返回"true"。我尝试了下面的方法,尽管我的列表中包含这两个值,但它返回false。请帮我检查一下我做错了什么,我使用的是JDK 11。
final Optional<CategoryModel> optionalData = variantCategoryModelList.stream()
.filter(valueData -> TEST1.equalsIgnoreCase(valueData.getName())
&& TEST2.equalsIgnoreCase(valueData.getName()))
.findFirst();
if (optionalData.isPresent()) {
return true;
}
英文:
I have an pojo class like the one below
public CategoryModel {
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
I have an arraylist created like the one below.
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);
I have to check, if the value "TEST1" & "TEST2" present in the list and return "true" if both values present in the "list" and I tried something like the one below, though my "list" has both the values, its returning false.Could you please help me check what I am doing wrong btw I am using JDK 11.
final Optional<CategoryModel> optionalData = variantCategoryModelList.stream().
filter(valueData -> TEST1.equalsIgnoreCase(valueData.getName())
&& TEST2.equalsIgnoreCase(valueData.getName())).findFirst();
if(optionalData.isPresent()){
return true;
}
答案1
得分: 6
你可以将你的 CategoryModel
映射到名称,并收集成字符串列表,然后调用 List.containsAll
:
return variantCategoryModelList.stream()
.map(CategoryModel::getName)
.collect(Collectors.toList())
.containsAll(Arrays.asList("TEST1", "TEST2"));
英文:
You could map your CategoryModel
to name and collect to list of strings and call List.containsAll
:
return variantCategoryModelList.stream()
.map(CategoryModel::getName)
.collect(Collectors.toList())
.containsAll(Arrays.asList("TEST1","TEST2"));
答案2
得分: 5
Set将是一个更自然(并且更快速)的数据结构:
return variantCategoryModelList.stream()
.map(CategoryModel::getName)
.collect(Collectors.toSet())
.containsAll(Set.of("TEST1", "TEST2"));
你的问题在于使用了“和”(&&
)而不是“或”。
所以:
Set<String> soughtNames = Set.of("TEST1", "TEST2");
return variantCategoryModelList.stream()
.filter(cm -> soughtNames.contains(cm.getName()))
.distinct()
.count() == 2L;
正如@fps评论所述,对于列表,需要使用distinct()
来防止接受["Test1", "Test1"],或者["Test1", "Test1", "Test2"]失败。
显然,这是低效的,因为在找到2个条目后,它仍然会遍历到末尾。
你想要:
Set<String> soughtNames = Set.of("TEST1", "TEST2");
return soughtNames.stream()
.allMatch(soughtName ->
variantCategoryModelList.stream()
.anyMatch(cm -> soughtName.equals(cm.getName())));
或者有点复古风格:
return
variantCategoryModelList.stream()
.anyMatch(cm -> "TEST1".equals(cm.getName())) &&
variantCategoryModelList.stream()
.anyMatch(cm -> "TEST2".equals(cm.getName()));
英文:
Set would be a more natural (and faster) data structure:
return variantCategoryModelList.stream()
.map(CategoryModel::getName)
.collect(Collectors.toSet())
.containsAll(Set.of("TEST1", "TEST2"));
Your problem was and (&&
) instead of or.
So:
Set<String> soughtNames = Set.of("TEST1", "TEST2");
return variantCategoryModelList.stream()
.filter(cm -> soughtNames.contains(cm.getName()))
.distinct()
.count() == 2L;
As @fps commented, distinct()
is needed on a list to prevent ["Test1", "Test1"] to be accepted, or ["Test1", "Test1", "Test2"] failing.
This is obviously inefficient as it will - having found 2 entries -, still walk to the end.
You want:
Set<String> soughtNames = Set.of("TEST1", "TEST2");
return soughtNames.stream()
.allMatch(soughtName ->
variantCategoryModelList.stream()
.anyMatch(cm -> soughtName.equals(cm.getName()));
Or a bit retro-style:
return
variantCategoryModelList.stream()
.anyMatch(cm -> "TEST1".equals(cm.getName())) &&
variantCategoryModelList.stream()
.anyMatch(cm -> "TEST2".equals(cm.getName()));
答案3
得分: 1
这是一种实现方式:
Set<String> set = Set.of("TEST1", "TEST2");
boolean result = list.stream()
.filter(cat -> set.contains(cat.getName().toUpperCase()))
.distinct()
.limit(2)
.count() == 2L;
这会对分类列表进行流处理,然后仅保留那些名称为TEST1
或TEST2
的分类。然后我们移除重复项,并在找到两个(已经是不同的)分类名称后停止。这确保了短路求值。最后,我们检查最终是否恰好有两个元素。
英文:
Here's a way to do it:
Set<String> set = Set.of("TEST1", "TEST2");
boolean result = list.stream()
.filter(cat -> set.contains(cat.getName().toUpperCase())
.distinct()
.limit(2)
.count() == 2L;
This streams the list of categories, then keeps only those categories whose name is either TEST1
or TEST2
. We then remove duplicates and stop after we've found two (already distinct) category names. This ensures short-circuiting. Finally, we check if we have exactly two elements at the end.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论