Imagine that you have a main class - a simulator - which uses two other classes - Manufacturers and Appraisers , which implement the interfaces IProducer and IEvaluator, respectively.
IProducer implementations yield results, while IEvaluator implementations evaluate these results. The simulator controls the flow of work by requesting an implementation of IProducer and passing the results to an instance of IEvaluator.
The actual implementation of the Producer and Appraiser is known at runtime, at compile time I only know their interfaces. See an example below.
package com.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; interface IProducer<T extends Comparable<T>> { public Map<Integer, T> getResults(); } class ProducerA implements IProducer<String> { @Override public Map<Integer, String> getResults() { Map<Integer, String> result = new HashMap<Integer, String>(); result.put(1, "A"); result.put(2, "B"); result.put(3, "B"); return result; } } class ProducerB implements IProducer<Integer> { @Override public Map<Integer, Integer> getResults() { Map<Integer, Integer> result = new HashMap<Integer, Integer>(); result.put(1, 10); result.put(2, 30); result.put(3, 30); return result; } } interface IEvaluator { public <T extends Comparable<T>> double evaluate(Map<Integer, T> results, Map<Integer, Double> groundTruth); } class KendallTauB implements IEvaluator { @Override public <T extends Comparable<T>> double evaluate(Map<Integer, T> results, Map<Integer, Double> groundTruth) { int concordant = 0, discordant = 0, tiedRanks = 0, tiedCapabilities = 0; for (Entry<Integer, T> rank1 : results.entrySet()) { for (Entry<Integer, T> rank2 : results.entrySet()) { if (rank1.getKey() < rank2.getKey()) { final T r1 = rank1.getValue(); final T r2 = rank2.getValue(); final Double c1 = groundTruth.get(rank1.getKey()); final Double c2 = groundTruth.get(rank2.getKey()); final int ranksDiff = r1.compareTo(r2); final int actualDiff = c1.compareTo(c2); if (ranksDiff * actualDiff > 0) { concordant++; } else if (ranksDiff * actualDiff < 0) { discordant++; } else { if (ranksDiff == 0) tiedRanks++; if (actualDiff == 0) tiedCapabilities++; } } } } final double n = results.size() * (results.size() - 1d) / 2d; return (concordant - discordant) / Math.sqrt((n - tiedRanks) * (n - tiedCapabilities)); } } public class Simulator { public static void main(String[] args) {
This code compiles without warning, and also works as it should. This is the solution to the question I asked before , so this is kind of the next question.
Using the code above, imagine that you want to save the result of a call to manufacturer.getResults () in a variable (which will later be used in a call to the calculateator.evaluate (results, groundTruth) method). What will be the type of this variable?
Map <Integer ,? >, Map <Integer ,? extends Comparable <โ? Make the main method common and use a common type? Nothing I've tried so far works. The compiler complains about every type I came up with.
public static void main(String[] args) {
It seems that the producer .getResults () returns something that cannot be statically expressed in Java. Is this a mistake, or am I missing something?