英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论