有没有办法在不使用循环的情况下获取列表中对象的索引

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

我打赌你正在寻找 方式:

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 使用 CollectionSet 而不是 List,那么最后一行更直接:

    product.setGalleryImages(galleryImages);