diff --git a/src/java/htsjdk/variant/vcf/VCFCompoundHeaderLine.java b/src/java/htsjdk/variant/vcf/VCFCompoundHeaderLine.java index 1a2d773612..48e0cdf0db 100644 --- a/src/java/htsjdk/variant/vcf/VCFCompoundHeaderLine.java +++ b/src/java/htsjdk/variant/vcf/VCFCompoundHeaderLine.java @@ -249,16 +249,34 @@ protected String toStringEncoding() { } /** - * returns true if we're equal to another compounder header line + * returns true if we're equal to another compound header line * @param o a compound header line * @return true if equal */ - public boolean equals(Object o) { - if (!(o instanceof VCFCompoundHeaderLine)) + @Override + public boolean equals(final Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() || ! super.equals(o) ) { return false; - VCFCompoundHeaderLine other = (VCFCompoundHeaderLine) o; - return equalsExcludingDescription(other) && - description.equals(other.description); + } + + final VCFCompoundHeaderLine that = (VCFCompoundHeaderLine) o; + return equalsExcludingDescription(that) && + description.equals(that.description); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + name.hashCode(); + result = 31 * result + count; + result = 31 * result + (countType != null ? countType.hashCode() : 0); // only nullable field according to validate() + result = 31 * result + description.hashCode(); + result = 31 * result + type.hashCode(); + result = 31 * result + lineType.hashCode(); + return result; } public boolean equalsExcludingDescription(VCFCompoundHeaderLine other) { diff --git a/src/java/htsjdk/variant/vcf/VCFContigHeaderLine.java b/src/java/htsjdk/variant/vcf/VCFContigHeaderLine.java index 64c5d7f8f5..12e400c95c 100644 --- a/src/java/htsjdk/variant/vcf/VCFContigHeaderLine.java +++ b/src/java/htsjdk/variant/vcf/VCFContigHeaderLine.java @@ -34,6 +34,8 @@ /** * A special class representing a contig VCF header line. Knows the true contig order and sorts on that * + * Note: this class has a natural ordering that is inconsistent with equals() + * * @author mdepristo */ public class VCFContigHeaderLine extends VCFSimpleHeaderLine { @@ -82,6 +84,26 @@ public SAMSequenceRecord getSAMSequenceRecord() { return record; } + @Override + public boolean equals(final Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() || ! super.equals(o) ) { + return false; + } + + final VCFContigHeaderLine that = (VCFContigHeaderLine) o; + return contigIndex.equals(that.contigIndex); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + contigIndex.hashCode(); + return result; + } + /** * IT IS CRITICAL THAT THIS BE OVERRIDDEN SO WE SORT THE CONTIGS IN THE CORRECT ORDER */ diff --git a/src/java/htsjdk/variant/vcf/VCFHeader.java b/src/java/htsjdk/variant/vcf/VCFHeader.java index f763729885..f0c432b3a0 100644 --- a/src/java/htsjdk/variant/vcf/VCFHeader.java +++ b/src/java/htsjdk/variant/vcf/VCFHeader.java @@ -32,6 +32,7 @@ import htsjdk.variant.utils.GeneralUtils; import htsjdk.variant.variantcontext.VariantContextComparator; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -57,7 +58,8 @@ *
* A class representing the VCF header */ -public class VCFHeader { +public class VCFHeader implements Serializable { + public static final long serialVersionUID = 1L; // the mandatory header fields public enum HEADER_FIELDS { diff --git a/src/java/htsjdk/variant/vcf/VCFHeaderLine.java b/src/java/htsjdk/variant/vcf/VCFHeaderLine.java index 284f0d4520..00d0f45f0f 100644 --- a/src/java/htsjdk/variant/vcf/VCFHeaderLine.java +++ b/src/java/htsjdk/variant/vcf/VCFHeaderLine.java @@ -27,6 +27,7 @@ import htsjdk.tribble.TribbleException; +import java.io.Serializable; import java.util.Map; @@ -37,7 +38,9 @@ * * A class representing a key=value entry in the VCF header */ -public class VCFHeaderLine implements Comparable { +public class VCFHeaderLine implements Comparable, Serializable { + public static final long serialVersionUID = 1L; + protected static final boolean ALLOW_UNBOUND_DESCRIPTIONS = true; protected static final String UNBOUND_DESCRIPTION = "Not provided in original VCF header"; @@ -101,10 +104,25 @@ protected String toStringEncoding() { return mKey + "=" + mValue; } - public boolean equals(Object o) { - if ( !(o instanceof VCFHeaderLine) ) + @Override + public boolean equals(final Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { return false; - return mKey.equals(((VCFHeaderLine)o).getKey()) && mValue.equals(((VCFHeaderLine)o).getValue()); + } + + final VCFHeaderLine that = (VCFHeaderLine) o; + return mKey.equals(that.mKey) && // key not nullable + (mValue != null ? mValue.equals(that.mValue) : that.mValue == null); // value is nullable + } + + @Override + public int hashCode() { + int result = mKey.hashCode(); + result = 31 * result + (mValue != null ? mValue.hashCode() : 0); + return result; } public int compareTo(Object other) { diff --git a/src/java/htsjdk/variant/vcf/VCFSimpleHeaderLine.java b/src/java/htsjdk/variant/vcf/VCFSimpleHeaderLine.java index 16e90e3409..3401d08315 100644 --- a/src/java/htsjdk/variant/vcf/VCFSimpleHeaderLine.java +++ b/src/java/htsjdk/variant/vcf/VCFSimpleHeaderLine.java @@ -98,18 +98,26 @@ protected String toStringEncoding() { return getKey() + "=" + VCFHeaderLine.toStringEncoding(map); } - public boolean equals(Object o) { - if ( !(o instanceof VCFSimpleHeaderLine) ) - return false; - VCFSimpleHeaderLine other = (VCFSimpleHeaderLine)o; - if ( !name.equals(other.name) || genericFields.size() != other.genericFields.size() ) + @Override + public boolean equals( final Object o ) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() || ! super.equals(o) ) { return false; - for ( Map.Entry