diff --git a/source/net/filebot/format/MediaBindingBean.java b/source/net/filebot/format/MediaBindingBean.java index 66301960..72561dd1 100644 --- a/source/net/filebot/format/MediaBindingBean.java +++ b/source/net/filebot/format/MediaBindingBean.java @@ -938,13 +938,7 @@ public class MediaBindingBean { // still no good match found -> just take the most probable video from the same folder if (videos.size() > 0) { - sort(videos, new SimilarityComparator(FileUtilities.getName(getMediaFile())) { - - @Override - public int compare(Object o1, Object o2) { - return super.compare(FileUtilities.getName((File) o1), FileUtilities.getName((File) o2)); - } - }); + sort(videos, new SimilarityComparator(FileUtilities.getName(getMediaFile()), FileUtilities::getName)); return videos.get(0); } } diff --git a/source/net/filebot/similarity/SimilarityComparator.java b/source/net/filebot/similarity/SimilarityComparator.java index 98486575..0d4aced0 100644 --- a/source/net/filebot/similarity/SimilarityComparator.java +++ b/source/net/filebot/similarity/SimilarityComparator.java @@ -1,44 +1,46 @@ - package net.filebot.similarity; +import static java.util.Collections.*; +import java.util.Collection; +import java.util.Collections; import java.util.Comparator; +import java.util.function.Function; - -public class SimilarityComparator implements Comparator { +public class SimilarityComparator implements Comparator { protected SimilarityMetric metric; - protected Object[] paragon; + protected Collection

paragon; + protected Function> mapper; - public SimilarityComparator(SimilarityMetric metric, Object[] paragon) { + public SimilarityComparator(SimilarityMetric metric, Collection

paragon, Function> mapper) { this.metric = metric; this.paragon = paragon; + this.mapper = mapper; } - - public SimilarityComparator(Object... paragon) { - this(new NameSimilarityMetric(), paragon); + public SimilarityComparator(P paragon, Function mapper) { + this(new NameSimilarityMetric(), singleton(paragon), mapper.andThen(Collections::singleton)); } - @Override - public int compare(Object o1, Object o2) { - float f1 = getMaxSimilarity(o1); - float f2 = getMaxSimilarity(o2); - - if (f1 == f2) - return 0; - - return f1 > f2 ? -1 : 1; + public int compare(T o1, T o2) { + return Double.compare(getSimilarity(o2), getSimilarity(o1)); } + private static final double ZERO = 0; - public float getMaxSimilarity(Object obj) { - float m = 0; - for (Object it : paragon) { - m += (it != null) ? metric.getSimilarity(obj, it) : 0; + public double getSimilarity(T value) { + return paragon.stream().mapToDouble((it) -> accumulateSimilarity(it, value)).average().orElse(ZERO); + } + + private double accumulateSimilarity(P paragon, T value) { + if (paragon == null) { + return ZERO; } - return m / paragon.length; + + return mapper.apply(value).stream().mapToDouble((it) -> it == null ? ZERO : (double) metric.getSimilarity(paragon, it)).max().orElse(ZERO); } + } diff --git a/test/net/filebot/similarity/SimilarityComparatorTest.java b/test/net/filebot/similarity/SimilarityComparatorTest.java new file mode 100644 index 00000000..16bdd5a1 --- /dev/null +++ b/test/net/filebot/similarity/SimilarityComparatorTest.java @@ -0,0 +1,49 @@ +package net.filebot.similarity; + +import static java.util.Arrays.*; +import static java.util.Collections.*; +import static org.junit.Assert.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +public class SimilarityComparatorTest { + + private static List generateWords() { + return asList("Hello", "Hallo", "12345", "Holla", "Hey", "0123456789", "Hello World", "Hello Test"); + } + + private static Map generateTranslations() { + Map m = new HashMap<>(); + m.put("Hello", "Hello"); + m.put("Hallo", "Hello"); + m.put("Holla", "Hello"); + m.put("Hey", "Hello"); + return m; + } + + @Test + public void defaultUsage() { + SimilarityComparator c = new SimilarityComparator("Hello", String::toString); + + List phrases = generateWords(); + phrases.sort(c); + + assertEquals("[Hello, Hello Test, Hello World, Hallo, 12345, Holla, Hey, 0123456789]", phrases.toString()); + } + + @Test + public void accumulateMapper() { + Map dict = generateTranslations(); + SimilarityComparator c = new SimilarityComparator(new NameSimilarityMetric(), singleton("Hello"), (it) -> asList(it, dict.get(it))); + + List phrases = generateWords(); + phrases.sort(c); + + assertEquals("[Hello, Hallo, Holla, Hey, Hello Test, Hello World, 12345, 0123456789]", phrases.toString()); + } + +} diff --git a/test/net/filebot/similarity/SimilarityTestSuite.java b/test/net/filebot/similarity/SimilarityTestSuite.java index 9db50d04..2a650b51 100644 --- a/test/net/filebot/similarity/SimilarityTestSuite.java +++ b/test/net/filebot/similarity/SimilarityTestSuite.java @@ -1,14 +1,11 @@ - package net.filebot.similarity; - import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; - @RunWith(Suite.class) -@SuiteClasses( { SeriesNameMatcherTest.class, SeasonEpisodeMatcherTest.class, NameSimilarityMetricTest.class, NumericSimilarityMetricTest.class, SeasonEpisodeMetricTest.class }) +@SuiteClasses({ SeriesNameMatcherTest.class, SeasonEpisodeMatcherTest.class, NameSimilarityMetricTest.class, NumericSimilarityMetricTest.class, SeasonEpisodeMetricTest.class, SimilarityComparatorTest.class }) public class SimilarityTestSuite { }