有没有办法在不使用循环的情况下获取列表中对象的索引
Is there a way to get the index of an object in a list without using a loop
诀窍是这个对象 MediaContainerModel
直接从 Object
继承 equals(Object)
而我不能也不想在它的 class定义。这是我目前拥有的:
private void addMediaContainer(MediaContainerModel newMediaContainer, ProductModel product) {
List<MediaContainerModel> galleryImages = new ArrayList<>(product.getGalleryImages());
MediaContainerModel inserted = null;
// if a MediaContainer with same qualifier as newMediaContainer already exists, replace it
// with the new one to prevent duplicates
for (int i = 0; i < galleryImages.size(); i++) {
if (galleryImages.get(i).getQualifier().equals(newMediaContainer.getQualifier())) {
inserted = galleryImages.set(i, newMediaContainer);
}
}
// if not, add it
if (inserted == null) {
galleryImages.add(newMediaContainer);
galleryImages.sort((image1, image2) -> image2.getQualifier().compareTo(image1.getQualifier()));
}
product.setGalleryImages(galleryImages);
}
我想通过仅覆盖此方法的 MediaContainerModel.equals(Object)
来做同样的事情,而无需丑陋的 for 循环,这样我就可以使用 List.indexOf(Object)
或其他带有 lambda 的东西。这在 Java 中可能吗?如果是这样怎么办?谢谢!
without using a loop
我打赌你正在寻找 java-stream 方式:
List<MediaContainerModel> galleryImages = new ArrayList<>(product.getGalleryImages());
galleryImages.stream()
.filter(image -> newMediaContainer.getQualifier() // filter the equal ones
.equals(image.getQualifier()))
.findAny() // find any existing
.ifPresent(image -> { // add if present
galleryImages.add(newMediaContainer);
galleryImages.sort(Comparator.comparing(MediaContainerModel::getQualifier));
});
product.setGalleryImages(galleryImages);
几点注意事项:
过滤使用穷举迭代以及for-loop
,这意味着所有元素都被迭代并且多个相等的MediaContainerModel
对象具有相同的限定符。只要你想找有没有合格的(findAny
)就可以了。否则,要找到最后一个,您必须将此行替换为:
.reduce((first, second) -> second)
使用Java流API的结果有点笨拙。我看到您插入了一个新元素并对列表进行排序,这意味着您的意图是让列表始终保持排序。如果不允许重复值,我建议使用 TreeSet
来保持元素在添加或删除时排序。整个解决方案会更简单:
Set<MediaContainerModel> galleryImages = new TreeSet<>(Comparator.comparing(MediaContainerModel::getQualifier));
galleryImages.addAll(product.getGalleryImages());
galleryImages.add(newMediaContainer); // won't be added if is already present
product.setGalleryImages(new ArrayList<>(galleryImages));
...如果 ProductModel
使用 Collection
或 Set
而不是 List
,那么最后一行更直接:
product.setGalleryImages(galleryImages);
诀窍是这个对象 MediaContainerModel
直接从 Object
继承 equals(Object)
而我不能也不想在它的 class定义。这是我目前拥有的:
private void addMediaContainer(MediaContainerModel newMediaContainer, ProductModel product) {
List<MediaContainerModel> galleryImages = new ArrayList<>(product.getGalleryImages());
MediaContainerModel inserted = null;
// if a MediaContainer with same qualifier as newMediaContainer already exists, replace it
// with the new one to prevent duplicates
for (int i = 0; i < galleryImages.size(); i++) {
if (galleryImages.get(i).getQualifier().equals(newMediaContainer.getQualifier())) {
inserted = galleryImages.set(i, newMediaContainer);
}
}
// if not, add it
if (inserted == null) {
galleryImages.add(newMediaContainer);
galleryImages.sort((image1, image2) -> image2.getQualifier().compareTo(image1.getQualifier()));
}
product.setGalleryImages(galleryImages);
}
我想通过仅覆盖此方法的 MediaContainerModel.equals(Object)
来做同样的事情,而无需丑陋的 for 循环,这样我就可以使用 List.indexOf(Object)
或其他带有 lambda 的东西。这在 Java 中可能吗?如果是这样怎么办?谢谢!
without using a loop
我打赌你正在寻找 java-stream 方式:
List<MediaContainerModel> galleryImages = new ArrayList<>(product.getGalleryImages());
galleryImages.stream()
.filter(image -> newMediaContainer.getQualifier() // filter the equal ones
.equals(image.getQualifier()))
.findAny() // find any existing
.ifPresent(image -> { // add if present
galleryImages.add(newMediaContainer);
galleryImages.sort(Comparator.comparing(MediaContainerModel::getQualifier));
});
product.setGalleryImages(galleryImages);
几点注意事项:
过滤使用穷举迭代以及
for-loop
,这意味着所有元素都被迭代并且多个相等的MediaContainerModel
对象具有相同的限定符。只要你想找有没有合格的(findAny
)就可以了。否则,要找到最后一个,您必须将此行替换为:.reduce((first, second) -> second)
使用Java流API的结果有点笨拙。我看到您插入了一个新元素并对列表进行排序,这意味着您的意图是让列表始终保持排序。如果不允许重复值,我建议使用
TreeSet
来保持元素在添加或删除时排序。整个解决方案会更简单:Set<MediaContainerModel> galleryImages = new TreeSet<>(Comparator.comparing(MediaContainerModel::getQualifier)); galleryImages.addAll(product.getGalleryImages()); galleryImages.add(newMediaContainer); // won't be added if is already present product.setGalleryImages(new ArrayList<>(galleryImages));
...如果
ProductModel
使用Collection
或Set
而不是List
,那么最后一行更直接:product.setGalleryImages(galleryImages);