From d27129ef977c4d85fd69b648800307e45244a765 Mon Sep 17 00:00:00 2001 From: Joel Thibault Date: Wed, 7 Nov 2018 14:07:28 -0500 Subject: [PATCH] Let IntelliJ fix equals() and hashCode() for classes with problems --- .../java/htsjdk/samtools/LinearIndex.java | 19 ++++------ .../htsjdk/samtools/cram/common/Version.java | 29 +++++++++------ .../CanonicalHuffmanIntegerEncoding.java | 22 +++++++---- .../readfeatures/BaseQualityScore.java | 26 +++++++------ .../cram/encoding/readfeatures/Bases.java | 25 ++++++++----- .../cram/encoding/readfeatures/Deletion.java | 23 +++++++----- .../cram/encoding/readfeatures/HardClip.java | 23 +++++++----- .../encoding/readfeatures/InsertBase.java | 27 ++++++++------ .../cram/encoding/readfeatures/Insertion.java | 24 ++++++++---- .../cram/encoding/readfeatures/Padding.java | 23 +++++++----- .../cram/encoding/readfeatures/ReadBase.java | 27 ++++++++------ .../cram/encoding/readfeatures/RefSkip.java | 23 +++++++----- .../cram/encoding/readfeatures/Scores.java | 25 ++++++++----- .../cram/encoding/readfeatures/SoftClip.java | 25 ++++++++----- .../encoding/readfeatures/Substitution.java | 35 ++++++++---------- .../samtools/cram/structure/CramHeader.java | 37 ++++++++++--------- .../samtools/cram/structure/ReadTag.java | 37 +++++++++++-------- src/main/java/htsjdk/tribble/index/Block.java | 20 +++++++--- .../tribble/index/linear/LinearIndex.java | 11 +++--- .../cram/encoding/ReadFeaturesTest.java | 28 ++++++++++++++ 20 files changed, 313 insertions(+), 196 deletions(-) create mode 100644 src/test/java/htsjdk/samtools/cram/encoding/ReadFeaturesTest.java diff --git a/src/main/java/htsjdk/samtools/LinearIndex.java b/src/main/java/htsjdk/samtools/LinearIndex.java index bccdfe8806..7ebd6bee57 100644 --- a/src/main/java/htsjdk/samtools/LinearIndex.java +++ b/src/main/java/htsjdk/samtools/LinearIndex.java @@ -24,6 +24,7 @@ package htsjdk.samtools; import java.util.Arrays; +import java.util.Objects; /** * The linear index associated with a given reference in a BAM index. @@ -103,23 +104,19 @@ public int getIndexStart() { } @Override - public boolean equals(final Object o) { + public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - - final LinearIndex that = (LinearIndex) o; - - if (mIndexStart != that.mIndexStart) return false; - if (mReferenceSequence != that.mReferenceSequence) return false; - if (!Arrays.equals(mIndexEntries, that.mIndexEntries)) return false; - - return true; + LinearIndex that = (LinearIndex) o; + return mReferenceSequence == that.mReferenceSequence && + mIndexStart == that.mIndexStart && + Arrays.equals(mIndexEntries, that.mIndexEntries); } @Override public int hashCode() { - int result = mReferenceSequence; - result = 31 * result + mIndexStart; + + int result = Objects.hash(mReferenceSequence, mIndexStart); result = 31 * result + Arrays.hashCode(mIndexEntries); return result; } diff --git a/src/main/java/htsjdk/samtools/cram/common/Version.java b/src/main/java/htsjdk/samtools/cram/common/Version.java index d20ecf9fc1..133fc2fa1d 100644 --- a/src/main/java/htsjdk/samtools/cram/common/Version.java +++ b/src/main/java/htsjdk/samtools/cram/common/Version.java @@ -1,5 +1,7 @@ package htsjdk.samtools.cram.common; +import java.util.Objects; + /** * A class to represent a version information, 3 number: major, minor and build number. */ @@ -44,20 +46,23 @@ public int compareTo(@SuppressWarnings("NullableProblems") final Version o) { return build - o.build; } - /** - * Check if another version is exactly the same as this one. - * - * @param obj another version object - * @return true if both versions are the same, false otherwise. - */ + public boolean compatibleWith(final Version version) { + return compareTo(version) >= 0; + } + @Override - public boolean equals(final Object obj) { - if (obj == null || !(obj instanceof Version)) return false; - final Version version = (Version) obj; - return major == version.major && minor == version.minor; + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Version version = (Version) o; + return major == version.major && + minor == version.minor && + build == version.build; } - public boolean compatibleWith(final Version version) { - return compareTo(version) >= 0; + @Override + public int hashCode() { + + return Objects.hash(major, minor, build); } } \ No newline at end of file diff --git a/src/main/java/htsjdk/samtools/cram/encoding/huffman/codec/CanonicalHuffmanIntegerEncoding.java b/src/main/java/htsjdk/samtools/cram/encoding/huffman/codec/CanonicalHuffmanIntegerEncoding.java index c37820d33a..9a549ce54d 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/huffman/codec/CanonicalHuffmanIntegerEncoding.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/huffman/codec/CanonicalHuffmanIntegerEncoding.java @@ -28,12 +28,12 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Map; +import java.util.Objects; public class CanonicalHuffmanIntegerEncoding implements Encoding { private static final EncodingID ENCODING_ID = EncodingID.HUFFMAN; private int[] bitLengths; private int[] values; - private final ByteBuffer buf = ByteBuffer.allocate(1024 * 10); public CanonicalHuffmanIntegerEncoding() { } @@ -45,6 +45,7 @@ public EncodingID id() { @Override public byte[] toByteArray() { + final ByteBuffer buf = ByteBuffer.allocate(1024 * 10); buf.clear(); ITF8.writeUnsignedITF8(values.length, buf); for (final int value : values) @@ -89,12 +90,19 @@ public static EncodingParams toParam(final int[] bfValues, final int[] bfBitLens } @Override - public boolean equals(final Object obj) { - if (obj instanceof CanonicalHuffmanIntegerEncoding) { - final CanonicalHuffmanIntegerEncoding foe = (CanonicalHuffmanIntegerEncoding) obj; - return Arrays.equals(bitLengths, foe.bitLengths) && Arrays.equals(values, foe.values); + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CanonicalHuffmanIntegerEncoding that = (CanonicalHuffmanIntegerEncoding) o; + return Arrays.equals(bitLengths, that.bitLengths) && + Arrays.equals(values, that.values); + } + + @Override + public int hashCode() { - } - return false; + int result = Arrays.hashCode(bitLengths); + result = 31 * result + Arrays.hashCode(values); + return result; } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/BaseQualityScore.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/BaseQualityScore.java index 07ee30502f..640859f3a0 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/BaseQualityScore.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/BaseQualityScore.java @@ -18,6 +18,7 @@ package htsjdk.samtools.cram.encoding.readfeatures; import java.io.Serializable; +import java.util.Objects; /** * A read feature representing a single quality score in a read. @@ -57,21 +58,24 @@ public void setQualityScore(final byte qualityScore) { this.qualityScore = qualityScore; } - @Override - public boolean equals(final Object obj) { - if (!(obj instanceof BaseQualityScore)) - return false; - - final BaseQualityScore v = (BaseQualityScore) obj; - - return position == v.position && qualityScore == v.qualityScore; - - } - @Override public String toString() { return new StringBuilder().append((char) operator).append('@') .append(position).append('#').appendCodePoint(qualityScore).toString(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BaseQualityScore that = (BaseQualityScore) o; + return position == that.position && + qualityScore == that.qualityScore; + } + + @Override + public int hashCode() { + + return Objects.hash(position, qualityScore); + } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Bases.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Bases.java index b2f066b722..f542162ad1 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Bases.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Bases.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Objects; public class Bases implements Serializable, ReadFeature { @@ -59,18 +60,24 @@ public void setPosition(final int position) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof Bases)) - return false; - - final Bases bases = (Bases) obj; - - return position == bases.position && !Arrays.equals(this.bases, bases.bases); + public String toString() { + return getClass().getSimpleName() + "[" + "position=" + position + "; bases=" + new String(bases) + "] "; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Bases bases1 = (Bases) o; + return position == bases1.position && + Arrays.equals(bases, bases1.bases); } @Override - public String toString() { - return getClass().getSimpleName() + "[" + "position=" + position + "; bases=" + new String(bases) + "] "; + public int hashCode() { + + int result = Objects.hash(position); + result = 31 * result + Arrays.hashCode(bases); + return result; } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Deletion.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Deletion.java index b4a0181d8d..03dc3ce521 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Deletion.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Deletion.java @@ -18,6 +18,7 @@ package htsjdk.samtools.cram.encoding.readfeatures; import java.io.Serializable; +import java.util.Objects; /** * A read feature representing a deletion of one or more bases similar to {@link htsjdk.samtools.CigarOperator#D}. @@ -60,18 +61,22 @@ public void setLength(final int length) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof Deletion)) - return false; - - final Deletion deleteion = (Deletion) obj; - - return position == deleteion.position && length == deleteion.length; + public String toString() { + return String.valueOf((char) operator) + '@' + position + '+' + length; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Deletion deletion = (Deletion) o; + return position == deletion.position && + length == deletion.length; } @Override - public String toString() { - return String.valueOf((char) operator) + '@' + position + '+' + length; + public int hashCode() { + + return Objects.hash(position, length); } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/HardClip.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/HardClip.java index 0e5678bb42..86da05513b 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/HardClip.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/HardClip.java @@ -18,6 +18,7 @@ package htsjdk.samtools.cram.encoding.readfeatures; import java.io.Serializable; +import java.util.Objects; /** * A read feature representing a hard clip similar to {@link htsjdk.samtools.CigarOperator#H}. @@ -60,18 +61,22 @@ public void setLength(final int length) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof HardClip)) - return false; - - final HardClip hardClip = (HardClip) obj; - - return position == hardClip.position && length == hardClip.length; + public String toString() { + return getClass().getSimpleName() + "[" + "position=" + position + "; length=" + length + "] "; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + HardClip hardClip = (HardClip) o; + return position == hardClip.position && + length == hardClip.length; } @Override - public String toString() { - return getClass().getSimpleName() + "[" + "position=" + position + "; length=" + length + "] "; + public int hashCode() { + + return Objects.hash(position, length); } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/InsertBase.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/InsertBase.java index d4a611e8d8..8530e25eda 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/InsertBase.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/InsertBase.java @@ -18,6 +18,7 @@ package htsjdk.samtools.cram.encoding.readfeatures; import java.io.Serializable; +import java.util.Objects; /** * A read feature representing a single insert base. @@ -52,17 +53,6 @@ public void setPosition(final int position) { this.position = position; } - @Override - public boolean equals(final Object obj) { - if (!(obj instanceof InsertBase)) - return false; - - final InsertBase insertBase = (InsertBase) obj; - - return position == insertBase.position && base == insertBase.base; - - } - @Override public String toString() { return new StringBuilder().append((char) operator).append('@') @@ -76,4 +66,19 @@ public byte getBase() { public void setBase(final byte base) { this.base = base; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InsertBase that = (InsertBase) o; + return position == that.position && + base == that.base; + } + + @Override + public int hashCode() { + + return Objects.hash(position, base); + } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Insertion.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Insertion.java index 2055ba0fd3..c61fb1f491 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Insertion.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Insertion.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Objects; /** * A read feature representing a multi-base insertion. @@ -61,17 +62,24 @@ public void setSequence(final byte[] sequence) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof Insertion)) - return false; - - final Insertion insertion = (Insertion) obj; + public String toString() { + return getClass().getSimpleName() + "[" + "position=" + position + "; sequence=" + new String(sequence) + "] "; + } - return position == insertion.position && Arrays.equals(sequence, insertion.sequence); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Insertion insertion = (Insertion) o; + return position == insertion.position && + Arrays.equals(sequence, insertion.sequence); } @Override - public String toString() { - return getClass().getSimpleName() + "[" + "position=" + position + "; sequence=" + new String(sequence) + "] "; + public int hashCode() { + + int result = Objects.hash(position); + result = 31 * result + Arrays.hashCode(sequence); + return result; } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Padding.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Padding.java index f9a201f2db..327f7b3835 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Padding.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Padding.java @@ -18,6 +18,7 @@ package htsjdk.samtools.cram.encoding.readfeatures; import java.io.Serializable; +import java.util.Objects; /** * A read feature representing padding, similar to {@link htsjdk.samtools.CigarOperator#P}. @@ -61,18 +62,22 @@ public void setLength(final int length) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof Padding)) - return false; - - final Padding padding = (Padding) obj; - - return position == padding.position && length == padding.length; + public String toString() { + return String.valueOf((char) operator) + '@' + position + '+' + length; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Padding padding = (Padding) o; + return position == padding.position && + length == padding.length; } @Override - public String toString() { - return String.valueOf((char) operator) + '@' + position + '+' + length; + public int hashCode() { + + return Objects.hash(position, length); } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/ReadBase.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/ReadBase.java index f56d6775a0..6d3f375594 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/ReadBase.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/ReadBase.java @@ -18,6 +18,7 @@ package htsjdk.samtools.cram.encoding.readfeatures; import java.io.Serializable; +import java.util.Objects; /** * A read feature representing a single base with associated quality score. @@ -59,17 +60,6 @@ public void setQualityScore(final byte qualityScore) { this.qualityScore = qualityScore; } - @Override - public boolean equals(final Object obj) { - if (!(obj instanceof ReadBase)) - return false; - - final ReadBase readBase = (ReadBase) obj; - - return position == readBase.position && base == readBase.base && qualityScore == readBase.qualityScore; - - } - @Override public String toString() { return new StringBuilder(getClass().getSimpleName() + "[") @@ -87,4 +77,19 @@ public void setBase(final byte base) { this.base = base; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ReadBase readBase = (ReadBase) o; + return position == readBase.position && + base == readBase.base && + qualityScore == readBase.qualityScore; + } + + @Override + public int hashCode() { + + return Objects.hash(position, base, qualityScore); + } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/RefSkip.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/RefSkip.java index e9e5ae37eb..dda8333527 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/RefSkip.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/RefSkip.java @@ -18,6 +18,7 @@ package htsjdk.samtools.cram.encoding.readfeatures; import java.io.Serializable; +import java.util.Objects; /** * A read feature representing a reference skip similar to {@link htsjdk.samtools.CigarOperator#N}. @@ -61,18 +62,22 @@ public void setLength(final int length) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof RefSkip)) - return false; - - final RefSkip refSkip = (RefSkip) obj; - - return position == refSkip.position && length == refSkip.length; + public String toString() { + return String.valueOf((char) operator) + '@' + position + '+' + length; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RefSkip refSkip = (RefSkip) o; + return position == refSkip.position && + length == refSkip.length; } @Override - public String toString() { - return String.valueOf((char) operator) + '@' + position + '+' + length; + public int hashCode() { + + return Objects.hash(position, length); } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Scores.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Scores.java index bd409fd4b0..cebdbf1179 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Scores.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Scores.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Objects; /** * A read feature representing a contiguous stretch of quality scores in a read. @@ -62,18 +63,24 @@ public void setPosition(final int position) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof Scores)) - return false; - - final Scores scores = (Scores) obj; - - return position == scores.position && !Arrays.equals(this.scores, scores.scores); + public String toString() { + return getClass().getSimpleName() + "[" + "position=" + position + "; scores=" + new String(scores) + "] "; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Scores scores1 = (Scores) o; + return position == scores1.position && + Arrays.equals(scores, scores1.scores); } @Override - public String toString() { - return getClass().getSimpleName() + "[" + "position=" + position + "; scores=" + new String(scores) + "] "; + public int hashCode() { + + int result = Objects.hash(position); + result = 31 * result + Arrays.hashCode(scores); + return result; } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/SoftClip.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/SoftClip.java index 7eaac6727e..2ba27b17d9 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/SoftClip.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/SoftClip.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Objects; /** * A read feature representing a soft clip similar to {@link htsjdk.samtools.CigarOperator#S}. @@ -62,18 +63,24 @@ public void setPosition(final int position) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof SoftClip)) - return false; - - final SoftClip softClip = (SoftClip) obj; - - return position == softClip.position && !Arrays.equals(sequence, softClip.sequence); + public String toString() { + return getClass().getSimpleName() + "[" + "position=" + position + "; bases=" + new String(sequence) + "] "; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SoftClip softClip = (SoftClip) o; + return position == softClip.position && + Arrays.equals(sequence, softClip.sequence); } @Override - public String toString() { - return getClass().getSimpleName() + "[" + "position=" + position + "; bases=" + new String(sequence) + "] "; + public int hashCode() { + + int result = Objects.hash(position); + result = 31 * result + Arrays.hashCode(sequence); + return result; } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Substitution.java b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Substitution.java index 1747c44749..ffae6bc6b6 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Substitution.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/readfeatures/Substitution.java @@ -18,6 +18,7 @@ package htsjdk.samtools.cram.encoding.readfeatures; import java.io.Serializable; +import java.util.Objects; /** * A substitution event captured in read coordinates. It is characterized by position in read, read base and reference base. @@ -96,28 +97,24 @@ public void setReferenceBase(final byte referenceBase) { } @Override - public boolean equals(final Object obj) { - if (!(obj instanceof Substitution)) - return false; - - final Substitution substitution = (Substitution) obj; - - if (position != substitution.position) - return false; - - if ((code != substitution.code) & (code == NO_CODE || substitution.code == NO_CODE)) { - return false; - } + public String toString() { + return String.valueOf((char) operator) + '@' + position + '\\' + (char) base + (char) referenceBase; + } - if (code > NO_CODE && substitution.code > NO_CODE) { - if (referenceBase != substitution.referenceBase) return false; - if (base != substitution.base) return false; - } - return true; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Substitution that = (Substitution) o; + return position == that.position && + base == that.base && + referenceBase == that.referenceBase && + code == that.code; } @Override - public String toString() { - return String.valueOf((char) operator) + '@' + position + '\\' + (char) base + (char) referenceBase; + public int hashCode() { + + return Objects.hash(position, base, referenceBase, code); } } diff --git a/src/main/java/htsjdk/samtools/cram/structure/CramHeader.java b/src/main/java/htsjdk/samtools/cram/structure/CramHeader.java index 05e772a4e6..74d49cef13 100644 --- a/src/main/java/htsjdk/samtools/cram/structure/CramHeader.java +++ b/src/main/java/htsjdk/samtools/cram/structure/CramHeader.java @@ -21,6 +21,7 @@ import htsjdk.samtools.cram.common.Version; import java.util.Arrays; +import java.util.Objects; /** * A starting object when dealing with CRAM files. A {@link CramHeader} holds 2 things: 1. File format definition, including content id and @@ -85,24 +86,6 @@ public CramHeader clone() { } - /** - * Checks if content of a header is the same as this one. - * @param obj another header to compare to - * @return true if versions, ids and SAM file header are exactly the same, false otherwise - */ - @Override - public boolean equals(final Object obj) { - if (obj == null) return false; - if (!(obj instanceof CramHeader)) return false; - - final CramHeader header = (CramHeader) obj; - - if (getVersion().major != header.getVersion().major) return false; - //noinspection SimplifiableIfStatement - if (getVersion().minor != header.getVersion().minor) return false; - return Arrays.equals(id, header.id) && getSamFileHeader().equals(header.getSamFileHeader()); - } - /** * Get the {@link SAMFileHeader} object associated with this CRAM file header. * @return the SAM file header @@ -120,4 +103,22 @@ public Version getVersion() { } public void setVersion(final Version version) { this.version = version; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CramHeader that = (CramHeader) o; + return Objects.equals(version, that.version) && + Arrays.equals(id, that.id) && + Objects.equals(samFileHeader, that.samFileHeader); + } + + @Override + public int hashCode() { + + int result = Objects.hash(version, samFileHeader); + result = 31 * result + Arrays.hashCode(id); + return result; + } } diff --git a/src/main/java/htsjdk/samtools/cram/structure/ReadTag.java b/src/main/java/htsjdk/samtools/cram/structure/ReadTag.java index 791bf2cfe7..9795452143 100644 --- a/src/main/java/htsjdk/samtools/cram/structure/ReadTag.java +++ b/src/main/java/htsjdk/samtools/cram/structure/ReadTag.java @@ -31,6 +31,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.Charset; +import java.util.Objects; /** * CRAM counterpart of {@link htsjdk.samtools.SAMTag}. @@ -152,21 +153,6 @@ public int compareTo(@SuppressWarnings("NullableProblems") final ReadTag o) { return key.compareTo(o.key); } - @Override - public boolean equals(final Object obj) { - if (!(obj instanceof ReadTag)) - return false; - - final ReadTag foe = (ReadTag) obj; - return key.equals(foe.key) && (value == null && foe.value == null || value != null && value.equals(foe.value)); - - } - - @Override - public int hashCode() { - return key.hashCode(); - } - public Object getValue() { return value; } @@ -484,4 +470,25 @@ private static String readNullTerminatedString(final ByteBuffer byteBuffer) { byteBuffer.get(); return StringUtil.bytesToString(buf); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ReadTag readTag = (ReadTag) o; + return keyType3BytesAsInt == readTag.keyType3BytesAsInt && + type == readTag.type && + code == readTag.code && + index == readTag.index && + Objects.equals(key, readTag.key) && + Objects.equals(keyAndType, readTag.keyAndType) && + Objects.equals(keyType3Bytes, readTag.keyType3Bytes) && + Objects.equals(value, readTag.value); + } + + @Override + public int hashCode() { + + return Objects.hash(key, keyAndType, keyType3Bytes, keyType3BytesAsInt, type, value, code, index); + } } diff --git a/src/main/java/htsjdk/tribble/index/Block.java b/src/main/java/htsjdk/tribble/index/Block.java index 15ac7999de..507ca9405d 100644 --- a/src/main/java/htsjdk/tribble/index/Block.java +++ b/src/main/java/htsjdk/tribble/index/Block.java @@ -23,6 +23,8 @@ */ package htsjdk.tribble.index; +import java.util.Objects; + /** * Represents a contiguous block of bytes in a file, defined by a start position and size (in bytes) */ @@ -73,10 +75,18 @@ public long getSize() { return size; } - public boolean equals(final Object obj) { - if ( this == obj ) return true; - if ( ! (obj instanceof Block) ) return false; - final Block otherBlock = (Block)obj; - return this.startPosition == otherBlock.startPosition && this.size == otherBlock.size; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Block block = (Block) o; + return startPosition == block.startPosition && + size == block.size; + } + + @Override + public int hashCode() { + + return Objects.hash(startPosition, size); } } diff --git a/src/main/java/htsjdk/tribble/index/linear/LinearIndex.java b/src/main/java/htsjdk/tribble/index/linear/LinearIndex.java index 758a81859b..4923f21461 100644 --- a/src/main/java/htsjdk/tribble/index/linear/LinearIndex.java +++ b/src/main/java/htsjdk/tribble/index/linear/LinearIndex.java @@ -30,11 +30,7 @@ import java.io.InputStream; import java.io.PrintStream; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; +import java.util.*; /** * Index defined by dividing the genome by chromosome, then each chromosome into bins of fixed width (in @@ -313,6 +309,11 @@ public boolean equals(final Object obj) { && blocks.equals(other.blocks); } + @Override + public int hashCode() { + return Objects.hash(binWidth, longestFeature, nFeatures, name, blocks); + } + /** * @return Total size of all blocks */ diff --git a/src/test/java/htsjdk/samtools/cram/encoding/ReadFeaturesTest.java b/src/test/java/htsjdk/samtools/cram/encoding/ReadFeaturesTest.java new file mode 100644 index 0000000000..cb957546d4 --- /dev/null +++ b/src/test/java/htsjdk/samtools/cram/encoding/ReadFeaturesTest.java @@ -0,0 +1,28 @@ +package htsjdk.samtools.cram.encoding; + +import htsjdk.HtsjdkTest; +import htsjdk.samtools.cram.encoding.readfeatures.Bases; +import htsjdk.samtools.cram.encoding.readfeatures.Scores; +import htsjdk.samtools.cram.encoding.readfeatures.SoftClip; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class ReadFeaturesTest extends HtsjdkTest { + + // equals() was incorrect for these classes + + @Test + public void faultyEquality() { + final Bases b1 = new Bases(0, new byte[] {}); + final Bases b2 = new Bases(0, new byte[] {}); + Assert.assertEquals(b1, b2); + + final Scores s1 = new Scores(0, new byte[] {}); + final Scores s2 = new Scores(0, new byte[] {}); + Assert.assertEquals(s1, s2); + + final SoftClip sc1 = new SoftClip(0, new byte[] {}); + final SoftClip sc2 = new SoftClip(0, new byte[] {}); + Assert.assertEquals(sc1, sc2); + } +}