0

I have a unit test that checks the order of a sorted results list.

The strange thing is that the test always passes in intellij but always fails when I run from console ./gradlew

can it be that transform or other method works differently depending on the environment?

public List<Image> sortImages(List<Image> inputImages, UserInfo userInfo) {
    if (inputImages == null) {
        return null;
    }
    List<ImageScore> imageScoreList = createImageScoreListFromImageList(inputImages);
    Collections.sort(imageScoreList, imageScoreDescComparator);
    imageScoreList = getSubListIfListIsTooLong(userInfo, imageScoreList);
    List<Image> sortedImages = transformImageScoreListToImageList(imageScoreList);
    return sortedImages;
}

private List<ImageScore> getSubListIfListIsTooLong(UserInfo userInfo, List<ImageScore> imageScoreList) {
    if (userInfo != null && userInfo.channel != null && userInfo.channel.equals(UserInfo.UserChannel.CLIENT)) {
        if (imageScoreList.size() > VenueConfig.s.MAX_IMAGES_TO_RETURN_TO_CLIENT) {
            imageScoreList = imageScoreList.subList(0, VenueConfig.s.MAX_IMAGES_TO_RETURN_TO_CLIENT);
        }
    }
    return imageScoreList;
}

private List<Image> transformImageScoreListToImageList(List<ImageScore> imageScoreList) {
    Collection result = Collections2.transform(imageScoreList, new Function<ImageScore, Image>() {
        @Override
        public Image apply(ImageScore input) {
            return input.image;
        }
    });

    return new ArrayList(result);
}

private List<ImageScore> createImageScoreListFromImageList(List<Image> inputImages) {
    Collection result = Collections2.transform(inputImages, new Function<Image, ImageScore>() {
        @Override
        public ImageScore apply(Image input) {
            ImageScore imageScore = new ImageScore(input);
            imageScore.score = imageScoreCalculator.getScoreForImage(input);
            return imageScore;
        }
    });
    return new ArrayList(result);
}

Update:

I do the following logic:

1) transform Image to ImageScore (with elements {int score, Image image}) which also sets the score

2) I then sort according to the score

3) I then re-transform ImageScore to Image

how can I do this differently? as the sorting relay on the calculated score?

Elad Benda
  • 35,076
  • 87
  • 265
  • 471

1 Answers1

1

Yes, it could well be that.

The transform returns a Collection (which is not sorted, by definition) and provides no guarantee in it's documentation as to ordering.

It may seem to be always sorted, but this is implementation dependendant and nothing you should rely on.

If there is a logical ordering to your elements, you could try this:

Collections.sort(result);
return new ArrayList(result);

Otherwise, you could use some sort of helper function to test the equivalence of two lists without paying heed to the ordering.

vikingsteve
  • 38,481
  • 23
  • 112
  • 156
  • It problematic to me, I do the following logic: 1) transform `Image` to `ImageScore` (with elements `{int score, Image image}`) which also sets the score 2) I then sort according to the score 3) I then re-transform `ImageScore` to `Image` how can I do this differently? as the sorting relay on the calculated score? – Elad Benda Sep 23 '14 at 08:30
  • You could try using a utility method in your test assertion that tests if lists contain the same elements, irrespective of odering, like `CollectionUtils.isEqualCollection(...)` - link: http://stackoverflow.com/questions/1565214/is-there-a-way-to-check-if-two-collections-contain-the-same-elements-independen – vikingsteve Sep 23 '14 at 08:59
  • but i want to check the order. will Lists.transform preserve order? – Elad Benda Sep 23 '14 at 09:08
  • 1
    Ok, well - no, that's the thing, `Collections2.transform` is *not* guaranteed to preserve order. Why don't you just create a new `ArrayList` of `Image`, and populate it yourself, instead of using `Collections2.transform` ? – vikingsteve Sep 23 '14 at 09:29