Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change in the way equals() is evaluated for Results, Hits, Hsps.Modif…
…ied tests accordingly.
  • Loading branch information
paolopavan committed Oct 5, 2015
commit 26eaebf2cd88d069855645431124771de5348312
60 changes: 28 additions & 32 deletions biojava-core/src/main/java/org/biojava/nbio/core/search/io/Hit.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public abstract class Hit implements Iterable<Hsp>{
private final String hitId;
private final String hitDef;
private final String hitAccession;
/**
* the length of the hit sequence
*/
private final int hitLen;
private final List<Hsp> hsps;
private Sequence hitSequence;
Expand All @@ -35,44 +38,37 @@ public Hit(int hitNum, String hitId, String hitDef, String hitAccession, int hit
this.hsps = hsps;
this.hitSequence = hitSequence;
}

/**
* Experimental.
* Wants to return an hashcode designed to allow conceptual comparisons of search results.

@Override
public int hashCode() {
int hash = 3;
hash = 89 * hash + this.hitLen;
hash = 89 * hash + (this.hsps != null ? this.hsps.hashCode() : 0);
return hash;
}
/**
* Implements conceptual comparisons of search results.
* Fields unrelated to search are deliberately not considered.
*
* This latter wants to be a way to compare two hits such that
* if two different queries hit for example chromososome 1,
* with of course different alignments, they will remain still equals to comparison.
* @return
*/
public int hashCode(){
String allInOne = hitId+hitLen;
return allInOne.hashCode();
}
/**
* gets a String to be hashcoded representing contained hsp.
* @return null if hsp does not contain alignment information.
* @return an hashcode representing all hsp
*/
String getHspsHashString(){
String cat = ""+hashCode();
if (hsps != null){
for (Hsp h: hsps){
// hsp hashcode cannot be calculated
if (h.getHspQseq() == null && h.getHspIdentityString() == null && h.getHspHseq()==null) return null;
cat += h.getHspQseq()+"\n"+h.getHspIdentityString()+"\n"+h.getHspHseq()+"\n";
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return cat;
final Hit other = (Hit) obj;
if (this.hitLen != other.hitLen) {
return false;
}
if (this.hsps != other.hsps && (this.hsps == null || !this.hsps.equals(other.hsps))) {
return false;
}
return true;
}

@Override
public boolean equals(Object o){
if (!(o instanceof Hit)) return false;

return o.hashCode() == this.hashCode();
}
public int getHitNum() {
return hitNum;
}
Expand Down
45 changes: 31 additions & 14 deletions biojava-core/src/main/java/org/biojava/nbio/core/search/io/Hsp.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,43 @@ public abstract class Hsp <S extends Sequence<C>, C extends Compound> {
private Double percentageIdentity = null;
private Integer mismatchCount = null;
private SimpleSequencePair<S, C> returnAln;


@Override
public int hashCode() {
int hash = 5;
hash = 67 * hash + (this.hspQseq != null ? this.hspQseq.hashCode() : 0);
hash = 67 * hash + (this.hspHseq != null ? this.hspHseq.hashCode() : 0);
hash = 67 * hash + (this.hspIdentityString != null ? this.hspIdentityString.hashCode() : 0);
return hash;
}
/**
* Experimental.
* Wants to return an hashcode designed to allow conceptual comparisons of search results.
* Wants to implement conceptual comparisons of search results.
* Fields unrelated to search are deliberately not considered.
* @return
*
* In HSP case, alignment representation strings are considered.
* @return true if HSP alignments are the same,
* false otherwise or if alignment strings are undetermined
*/
public int hashCode(){
String allInOne = hspQseq+"\n"+hspIdentityString+"\n"+hspHseq;
return allInOne.hashCode();
}

@Override
public boolean equals(Object o){
if (!(o instanceof Hsp)) return false;
Hsp other = (Hsp)o;
//if (this.getRepresentationString()==null || other.getRepresentationString()==null) return false;

return o.hashCode() == this.hashCode();
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Hsp<?, ?> other = (Hsp<?, ?>) obj;
if ((this.hspQseq == null) ? (other.hspQseq != null) : !this.hspQseq.equals(other.hspQseq)) {
return false;
}
if ((this.hspHseq == null) ? (other.hspHseq != null) : !this.hspHseq.equals(other.hspHseq)) {
return false;
}
if ((this.hspIdentityString == null) ? (other.hspIdentityString != null) : !this.hspIdentityString.equals(other.hspIdentityString)) {
return false;
}
return true;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two comments here:

  • equals should not be implemented by comparing hashCodes. Hash codes do not guarantee equality. Hash equality is a necessary but not sufficient condition for equality (2 different objects can have the same hash)
  • the best way to implement a hashCode is to follow the indications in this SO thread. Actually if you are using eclipse it can even implement such a thing for you automatically, just go to 'Source' -> 'Generate hashCode and equals', you then only need to select which fields of the class should be used (I imagine other IDEs will have similar functions).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed the full stuff. I have revisited the way equality is
evaluated and I have modified properties accordingly.

2015-09-22 20:23 GMT+02:00 Jose Manuel Duarte notifications@github.com:

In biojava-core/src/main/java/org/biojava/nbio/core/search/io/Hsp.java
#329 (comment):

  • \* Experimental.
    
  • \* Wants to return an hashcode designed to allow conceptual comparisons of search results.
    
  • \* Fields unrelated to search are deliberately not considered.
    
  • \* @return
    
  • */
    
  • public int hashCode(){
  •    String allInOne = hspQseq+"\n"+hspIdentityString+"\n"+hspHseq;
    
  •    return allInOne.hashCode();
    
  • }
  • @OverRide
  • public boolean equals(Object o){
  •    if (!(o instanceof Hsp)) return false;
    
  •    return o.hashCode() == this.hashCode();
    
  • }

Two comments here:

equals should not be implemented by comparing hashCodes. Hash codes do
not guarantee equality. Hash equality is a necessary but not sufficient
condition for equality (2 different objects can have the same hash)

the best way to implement a hashCode is to follow the indications in this
SO thread
http://stackoverflow.com/questions/113511/best-implementation-for-hashcode-method.
Actually if you are using eclipse it can even implement such a thing for
you automatically, just go to 'Source' -> 'Generate hashCode and equals',
you then only need to select which fields of the class should be used (I
imagine other IDEs will have similar functions).

—
Reply to this email directly or view it on GitHub
https://github.com/biojava/biojava/pull/329/files#r40123811.


public SequencePair<S,C> getAlignment(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,41 @@ public Result(String program, String version, String reference, String dbFile, H
this.hits = hits;
this.querySequence = querySequence;
}

@Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + (this.queryID != null ? this.queryID.hashCode() : 0);
hash = 29 * hash + (this.queryDef != null ? this.queryDef.hashCode() : 0);
hash = 29 * hash + (this.hits != null ? this.hits.hashCode() : 0);
return hash;
}
/**
* Experimental.
* Wants to return an hashcode designed to allow conceptual comparisons of search results.
* Wants to implement conceptual comparisons of search results.
* Fields unrelated to search are deliberately not considered.
* @return
*/
public int hashCode(){
String prefix = queryID+queryDef;
String suffix="";
if (hits != null){
for (Hit h: hits) {
String hashString = h.getHspsHashString();
if (hashString== null) return prefix.hashCode();
suffix += hashString;
}
}
return (prefix+suffix).hashCode();
}

@Override
public boolean equals(Object o){
if (!(o instanceof Result)) return false;

return o.hashCode() == this.hashCode();
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Result other = (Result) obj;
if ((this.queryID == null) ? (other.queryID != null) : !this.queryID.equals(other.queryID)) {
return false;
}
if ((this.queryDef == null) ? (other.queryDef != null) : !this.queryDef.equals(other.queryDef)) {
return false;
}
if (this.hits != other.hits && (this.hits == null || !this.hits.equals(other.hits))) {
return false;
}
return true;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as above about hashCode and equals. Try using the eclipse built-in function to generate them.


public int getIterationNumber() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@
import org.junit.Ignore;

/**
* Designed by Paolo Pavan.
* You may want to find my contacts on Github and LinkedIn for code info
* or discuss major changes.
* https://github.com/paolopavan
*
* @author Paolo Pavan
*/

Expand Down Expand Up @@ -83,13 +78,42 @@ public void testHashCode() {
int expResult;
int result;

instance = hspImpl;
expResult = 71782805;
instance = new BlastHspBuilder()
.setHspNum(1)
.setHspBitScore(377.211)
.setHspEvalue(8.04143e-093)
.setHspQueryFrom(1)
.setHspQueryTo(224)
.setHspHitFrom(1035)
.setHspHitTo(811)
.setHspQueryFrame(-1)
.setHspIdentity(213)
.setHspPositive(213)
.setHspGaps(5)
.setHspAlignLen(227)
.setHspQseq("CTGACGACAGCCATGCACCACCTGTCTCGACTTTCCCCCGAAGGGCACCTAATGTATCTCTACCTCGTTAGTCGGATGTCAAGACCTGGTAAGGTTTTTTCGCGTATCTTCGAATTAAACCACATACTCCACTGCTTGTGCGG-CCCCCGTCAATTCCTTTGAGTTTCAACCTTGCGGCCGTACTCCC-AGGTGGA-TACTTATTGTGTTAACTCCGGCACGGAAGG")
.setHspHseq("CTGACGACAACCATGCACCACCTGTCTCAACTTTCCCC-GAAGGGCACCTAATGTATCTCTACTTCGTTAGTTGGATGTCAAGACCTGGTAAGGTT-CTTCGCGTTGCTTCGAATTAAACCACATACTCCACTGCTTGTGCGGGCCCCCGTCAATTCCTTTGAGTTTCAACCTTGCGGTCGTACTCCCCAGGTGGATTACTTATTGTGTTAACTCCGGCACAGAAGG")
.setHspIdentityString("||||||||| |||||||||||||||||| ||||||||| |||||||||||||||||||||||| |||||||| ||||||||||||||||||||||| ||||||| |||||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||||||||| ||||||||| ||||||| |||||||||||||||||||||||| |||||")
.createBlastHsp();

expResult = hspImpl.hashCode();
result = instance.hashCode();
assertEquals(expResult, result);

instance = uncompleteHsp;
expResult = 679;
instance = new BlastHspBuilder()
.setPercentageIdentity(100.00/100)
.setHspAlignLen(48)
.setMismatchCount(0)
.setHspGaps(0)
.setHspQueryFrom(1)
.setHspQueryTo(48)
.setHspHitFrom(344)
.setHspHitTo(391)
.setHspEvalue(4e-19)
.setHspBitScore(95.6)
.createBlastHsp();

expResult = uncompleteHsp.hashCode();
result = instance.hashCode();
assertEquals(expResult, result);

Expand All @@ -106,7 +130,7 @@ public void testHashCode() {
.setHspBitScore(95.6)
.createBlastHsp();

assertFalse(uncompleteHsp.hashCode() == uncompleteHsp2.hashCode());
assertEquals(uncompleteHsp.hashCode(), uncompleteHsp2.hashCode());
}

/**
Expand Down Expand Up @@ -137,7 +161,7 @@ public void testEquals() {

assertEquals(o, instance);

// example of Hsp retrieved from uncomplete report. The result is null, hance false
// example of Hsp retrieved from uncomplete report.
// (Those HSP may come from a tabular format, for example)
o = new BlastHspBuilder()
.setPercentageIdentity(100.00/100)
Expand All @@ -152,8 +176,7 @@ public void testEquals() {
.setHspBitScore(95.6)
.createBlastHsp();

// At now, check will return false as it could be not determined
assertFalse(uncompleteHsp.equals(o));
assertEquals(uncompleteHsp, o);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void testCreateObjects() throws Exception {
Hit expHit1res1;
Hsp expHsp1hit1res1;

String resource = "/org/biojava/nbio/core/search/io/blast/test.two-query.blasttxt";
String resource = "/org/biojava/nbio/core/search/io/blast/small-blastreport.blasttxt";
URL resourceURL = getClass().getResource(resource);
File file = new File(resourceURL.getFile());

Expand All @@ -87,25 +87,47 @@ public void testCreateObjects() throws Exception {

BlastHsp hsp1Hit1Res1 = new BlastHspBuilder()
.setHspNum(1)
.setPercentageIdentity(97.40/100)
.setHspAlignLen(77)
.setMismatchCount(2)
.setPercentageIdentity(100.0/100)
.setHspAlignLen(1567)
.setMismatchCount(0)
.setHspGaps(0)
.setHspQueryFrom(774)
.setHspQueryTo(850)
.setHspHitFrom(45396566)
.setHspQueryTo(45396336)
.setHspEvalue(1e-46)
.setHspBitScore(157)
.setHspQueryFrom(1)
.setHspQueryTo(1567)
.setHspHitFrom(616309)
.setHspQueryTo(617875)
.setHspEvalue(0)
.setHspBitScore(2894)
.createBlastHsp();

BlastHsp hsp1Hit1Res2 = new BlastHspBuilder()
.setHspNum(1)
.setPercentageIdentity(100.0/100)
.setHspAlignLen(1567)
.setMismatchCount(0)
.setHspGaps(0)
.setHspQueryFrom(1)
.setHspQueryTo(1567)
.setHspHitFrom(1278699)
.setHspQueryTo(1277133)
.setHspEvalue(0)
.setHspBitScore(2894)
.createBlastHsp();

List<Hsp> hsplist = new ArrayList();
hsplist.add(hsp1Hit1Res1);
hsplist.add(hsp1Hit1Res2);

BlastHit hit1Res1 = new BlastHitBuilder()
.setHitDef("chr15")
.setHitDef("CP000411")
.setHsps(hsplist)
.createBlastHit();
List<Hit> hitlist = new ArrayList();
hitlist.add(hit1Res1);

BlastResult res1 = new BlastResultBuilder()
.setQueryID("Query_1")
.setQueryDef("Dual oxidase (DUOX1_RAT)")
.setQueryID("CP000411_-_16S_rRNA")
.setQueryDef("CP000411_-_16S_rRNA")
.setHits(hitlist)
.createBlastResult();

expRes1 = results.get(0);
Expand Down Expand Up @@ -145,20 +167,10 @@ public void testCreateObjects() throws Exception {
.setHspBitScore(95.6)
.createBlastHsp();

hit1Res1 = new BlastHitBuilder()
.setHitDef("KF031625.1.1775")
.createBlastHit();

res1 = new BlastResultBuilder()
.setQueryID("1_759_906_F3")
.setQueryDef("1_759_906_F3")
.createBlastResult();

// results test
assertEquals(expRes1, res1);
// hit test
assertEquals(expHit1res1, hit1Res1);
// hsp test
assertEquals(expRes1.getQueryID(), "1_759_906_F3");
assertEquals(results2.size(), 298);
// only one hsp test
assertEquals(expHsp1hit1res1, hsp1Hit1Res1);
}

Expand Down
Loading