有没有人知道任何花哨的番石榴功能会为我做以下事情。
考虑我有一个对象列表。每个对象都有一个id。我有一个10个对象的列表,其中id为1到10.我想基于id获取特定对象。我通常做的是
private MyObject findMyObjectById(List<MyObject> items, Integer id) {
for (MyObject item : items) {
if (id.equals(item.getId())) {
return item;
}
}
return null;
}
这是冗长和重复的,因为我无法输入id(因为各种原因,getId不在我拥有的任何界面中)
有没有花哨的番石榴方法来做到这一点?
答案 0 :(得分:1)
在此示例中,我使用FluentIterable's firstMatch。
同样在大多数情况下,请避免返回null,而不是Optional。
private final int id;
public MyObject(final int id) {
this.id = id;
}
public int getId() {
return this.id;
}
@Override
public String toString() {
return "MyObject [id=" + this.id + "]";
}
public static Optional<MyObject> findFirstByFilter(final List<MyObject> myObjects, final Predicate<MyObject> filter) {
return FluentIterable.from(myObjects)
.firstMatch(filter);
}
public static Optional<MyObject> findFirstById(final List<MyObject> myObjects, final Integer id) {
return findFirstByFilter(myObjects, new Predicate<MyObject>() {
@Override
public boolean apply(final MyObject myObject) {
return myObject.getId() == id;
}
});
}
public static void main(final String... args) {
final List<MyObject> myObjects = ImmutableList.of(new MyObject(1), new MyObject(2));
final Optional<MyObject> found = findFirstById(myObjects, 2);
//MyObject [id=2]
System.out.println(found.orNull());
final Optional<MyObject> notFound = findFirstById(myObjects, 5);
//null
System.out.println(notFound.orNull());
}
Java 8版本:
private final int id;
public MyObject(final int id) {
this.id = id;
}
public int getId() {
return this.id;
}
@Override
public String toString() {
return "MyObject [id=" + this.id + "]";
}
public static void main(final String... args) {
final List<MyObject> myObjects = ImmutableList.of(new MyObject(1), new MyObject(2));
final Optional<MyObject> found = myObjects.stream()
.filter(myObject -> myObject.getId() == 2)
.findAny();
// MyObject [id=2]
System.out.println(found.orElse(null));
final Optional<MyObject> notFound = myObjects.stream()
.filter(myObject -> myObject.getId() == 5)
.findAny();
// null
System.out.println(notFound.orElse(null));
}
答案 1 :(得分:1)
我知道你不能总是修改你的代码到套件,但这是我在这里看到的模式(我现在找不到它)。我们现在在我们的实体对象,DTO等上使用了很多。
创建此界面:
public interface HasLongId {
public long getId();
}
现在在LongIds类中:
public static final Function<HasLongId, Long> GetIndex =
new Function<HasLongId, Long>() {
@Override
public Long apply(HasLongId hasId) {
return hasId.getId();
}
};
public static class NameMatcher implements Predicate<HasLongId> {
private final long id;
public NameMatcher(long id) {
this.id = id;
}
@Override public boolean apply(HasLongId hasId) {
return id == hasId.getId();
}
}
你可以这样做:
public static final <V extends HasLongId> Iterator<Long> of(Iterator<V> items) {
return Iterators.transform(items, GetIndex);
}
public static final <V extends HasLongId> String join(Iterable<V> items) {
return Joiner.on(',').skipNulls().join(of(items));
}
public static final <V extends HasLongId> ImmutableMap<Long, V> mapOf(Iterable<V> items) {
return Maps.uniqueIndex(items, GetIndex);
}
public static final <V extends HasLongId> V find(Iterable<V> iterable, Long id) {
return Iterables.find(iterable, new NameMatcher(id));
}
public static final <V extends HasLongId> boolean contains(V[] array, Long id) {
return Iterators.contains(of(Iterators.forArray(array)), id);
}
等等。 我们也有这个界面:
public interface HasName {
String getName();
}
包含名为Names的类,其中包含我们的实用程序方法。 希望这有点帮助。
答案 2 :(得分:0)