在这种情况下如何声明Java Comparable

时间:2019-06-07 17:16:53

标签: java generics

这是我正在上的课:

public class Thing<T extends Comparable<? super T>> {
   private Map<String, List<SourcedValue<T>>> properties;
}

然后,SourcedValue是这个:

public class SourcedValue<T extends Comparable<? super T>> 
                         implements Comparable<****?*****> {
  private T value;
  private List<Sources> sources;

  @Override
  public int compareTo(SourcedValue<****?****> other) {
    return value.compareTo(other);
  }
}

我在***?***中放什么?

我需要做的是使用创建List<SourcedValue<T>>并填充的某些convert方法对Thing中的Thing进行排序  properties(以及每个属性的List<SourcedValue<T>>)。

2 个答案:

答案 0 :(得分:0)

我不确定这是否会对您有所帮助,但这是我看到的实现您的要求的一种方法。如果能帮到您,我会很高兴。

public class SourcedValue<T extends Comparable<? super T>>
    implements Comparable<SourcedValue<? super T>> {
private T value;
private List<Integer> sources;

@Override
public int compareTo(SourcedValue<? super T> o) {
    return value.compareTo((T)o.value);
    }
}

这里使用super似乎是多余的。甚至下面的解决方案也应该产生相同的结果

public class SourcedValue<T extends Comparable<T>>
    implements Comparable<SourcedValue<T>> {
private T value;
private List<Integer> sources;

@Override
public int compareTo(SourcedValue<T> o) {
    return value.compareTo(o.value);
}
}

答案 1 :(得分:0)

这是我的处理方式:

TypedProperty.java

/**
 * A TypedProperty class - more than String.
 * @link https://stackoverflow.com/questions/56498727/how-to-declare-java-comparable-in-this-situation
 */
public class TypedProperty<T extends Comparable<T>> implements Comparable<TypedProperty<T>> {

    private final T value;
    private final Class<T> type;

    public TypedProperty(T value, Class<T> clazz) {
        this.value = value;
        this.type = clazz;
    }

    public T getValue() {
        return value;
    }

    public Class<T> getType() {
        return type;
    }

    @Override
    public int compareTo(TypedProperty<T> other) {
        return this.value.compareTo(other.value);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        TypedProperty<?> that = (TypedProperty<?>) o;

        if (!getValue().equals(that.getValue())) return false;
        return getType().equals(that.getType());
    }

    @Override
    public int hashCode() {
        int result = getValue().hashCode();
        result = 31 * result + getType().hashCode();
        return result;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("TypedProperty{");
        sb.append("value=").append(value);
        sb.append(", type=").append(type);
        sb.append('}');
        return sb.toString();
    }
}

JUnit测试以证明其有效:

import org.junit.Assert;
import org.junit.Test;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @link https://stackoverflow.com/questions/56498727/how-to-declare-java-comparable-in-this-situation
 */
public class TypedPropertyTest {

    @Test
    public void testConstructor_DateTypedProperty() throws ParseException {
        // setup
        String [] testDates = { "2019-06-07", "2018-03-17", "2017-01-01" };
        List<String> expected = Arrays.asList(testDates);
        Collections.sort(expected);
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        List<TypedProperty<Date>> typedProperties = new ArrayList<>();
        for (String testDate : testDates) {
            typedProperties.add(new TypedProperty<>(format.parse(testDate), Date.class));
        }
        // test
        Collections.sort(typedProperties);
        // assert
        for (int i = 0; i < typedProperties.size(); ++i) {
            Assert.assertEquals(format.parse(expected.get(i)), typedProperties.get(i).getValue());
        }
    }
}