我有以下字符串列表:
{"纽约","伦敦","巴黎","柏林","纽约" }
我正在尝试使用Guava库,我希望以这样的方式过滤此列表,我将只获得将等于我将提供的字符串的字符串。如果我有一个固定的价值,那就说“纽约"我会做以下事情:
Predicate<String> myCity = new Predicate<String>() {
@Override public boolean apply(String city) {
return city == "New York";
}
};
但是,如果我希望return语句是这样的:
return city == myStringVariable
我可以将该城市的参数提供给Predicate,还是以某种方式合并两个谓词?
答案 0 :(得分:8)
Guava通过Predicates
助手类提供了许多非常通用的Predicate
。
要过滤相等(对于String
或任何其他对象),它会提供equalTo()
谓词:
Predicate<String> myCity = Predicates.equalTo(myStringVariable);
更新以回答评论中的问题:如何在列表不是String
时过滤,而是过滤具有String
属性的对象。
您有几种选择,具体取决于您已有的选项:
使用命令性代码
对于一次性使用,除非您使用Java 8,否则使用功能构造有点冗长。请参阅Wiki中的FunctionalExplained页面。
private List<SomeObject> filterOnMyCity(List<SomeObject> list,
String value) {
List<SomeObject> result = new ArrayList<>();
for (SomeObject o : list) {
if (value.equals(o.getMyCity())) {
result.add(o);
}
}
return result;
}
使用ad-hoc谓词
class MyCityPredicate implements Predicate<SomeObject> {
private final String value;
public MyCityPredicate(String value) {
this.value = value;
}
@Override
public boolean apply(@Nullable SomeObject input) {
return input != null && value.equals(input.getPropertyX());
}
}
return FluentIterable.from(list)
.filter(new MyCityPredicate(myStringVariable))
.toList();
使用现有的Function
class MyCityFunction implements Function<SomeObject, String> {
@Override
public String apply(@Nullable SomeObject input) {
return input == null ? null : input.getPropertyX();
}
}
return FluentIterable.from(list)
.filter(Predicates.compose(
Predicates.equalTo(myStringVariable),
new MyCityFunction()))
.toList();
但是,我不会覆盖评论中提到的equals()
,它可能过于具体,不能说SomeObject
的2个实例等于它们的属性之一。如果您需要在不同的上下文中过滤2个不同的属性,它不会扩展。
如果你有Java 8,使用lambda表达式代码变得更加紧凑,你可以直接使用Stream
API,因此你不需要Guava 。 / p>
答案 1 :(得分:3)
要么使用Predicate的最终String或子类:
final String testStr = textbox.getText(); //for example
Predicate<String> myCity = new Predicate<String>() {
@Override public boolean apply(String city) {
return city.equals(testStr);
}
};
或
public class CityPredicate implements Predicate<String>{
String cityName;
public CityPredicate(String cityName){
this.cityName = cityName;
}
@Override public boolean apply(String city) {
return city.equals(cityName);
}
}
//Use example :
Predicate<String> myCity = new CityPredicate("New York");
正如@Sotirios Delimanolis告诉你的那样,总是将String与equals()进行比较
编辑:Frank Pavageau解决方案的示例: 鉴于你的班级:public class City{
String cityName;
public City(String cityName){
this.cityName=cityName;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof String){
return cityName.equals(obj);
}
return false;
}
}
List<City> cities = Lists.newArrayList(new City("New York"),new City("Chicago"));
Predicate<String> myCityPredicate = Predicates.equalTo("New York");
final List<City> res = Lists.newArrayList(Iterables.filter(cities , myCityPredicate));
//res.size() will be 1 and containing only your City("New York")
//To check whether it is present you can do :
final boolean isIn = Predicates.in(cities).apply("New York");
答案 2 :(得分:2)
您可以通过关闭其他变量来构造谓词
final String cityName = "New York";
Predicate<String> myCity = new Predicate<String>() {
@Override public boolean apply(String city) {
return city.equals(cityName);
}
};
请注意我如何比较字符串与equals
方法而不是==
引用相等运算符。请参阅下文了解原因。