Calculate the Hamming difference between two DNA strands Write a program that can calculate the Hamming difference between two DNA strands.
  
  GAGCCTACTAACGGGAT
     CATCGTAATGACGGCCT
     ^ ^ ^  ^ ^    ^^
  
  The Hamming distance between these two DNA strands is 7.




import java.util.Optional;


public class Hamming {
  public static int compute(String s1, String s2) {
    validateInputs(s1, s2);

    int hammingDistance = 0;
    int stringLength = s1.length();

    for (int i = 0; i &lt; stringLength; i++) {
      if (s1.charAt(i) != s2.charAt(i)) {
        hammingDistance++;
      }
    }
    return hammingDistance;
  }

  private static void validateInputs(String s1, String s2) {
    if (s1.length() != s2.length()) {
      throw new IllegalArgumentException();
    }
  }
}


Test suite:

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.junit.Test;

public class HammingTest {

    @Test
    public void testNoDifferenceBetweenIdenticalStrands() {
        assertThat(Hamming.compute("A", "A"), is(0));
    }

    @Test
    public void testCompleteHammingDistanceOfForSingleNucleotideStrand() {
        assertThat(Hamming.compute("A", "G"), is(1));
    }

    @Test
    public void testCompleteHammingDistanceForSmallStrand() {
        assertThat(Hamming.compute("AG", "CT"), is(2)); 
    }

    @Test
    public void testSmallHammingDistance() {
        assertThat(Hamming.compute("AT", "CT"), is(1));
    }

    @Test
    public void testSmallHammingDistanceInLongerStrand() {
        assertThat(Hamming.compute("GGACG", "GGTCG"), is(1));
    }

    @Test(expected = IllegalArgumentException.class)
    public void testValidatesFirstStrandNotLonger() {
        Hamming.compute("AAAG", "AAA");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testValidatesOtherStrandNotLonger() {
        Hamming.compute("AAA", "AAAG");
    }

    @Test
    public void testLargeHammingDistance() {
        assertThat(Hamming.compute("GATACA", "GCATAA"), is(4));
    }

    @Test
    public void testHammingDistanceInVeryLongStrand() {
        assertThat(Hamming.compute("GGACGGATTCTG", "AGGACGGATTCT"), is(9));
    }

}


Questions:


Am I using the correct data structures?
Can I improve performance? Right now it seems to be \$Θ(n)\$ since it has to check all the characters in the string.
Your code is really all that there is to it. It is clear and concise: one method to validate the input (validateInputs) and the rest of the method to calculate the Hamming distance with a simple loop.

A couple of comments:


In case of inputs of different length, you are (rightfully) throwing a IllegalArgumentException like this:

if (s1.length() != s2.length()) {
  throw new IllegalArgumentException();
}


This is a generic IllegalArgumentException with no message. You might want to add a message so that it is clearer to the caller what went wrong; it would also help the debugging (imagine a bigger application).
To resemble what is done by the existing Objects class, you could rename your validating method to requireSameLength and make it return the length:

private static int requireSameLength(String s1, String s2) {
    if (s1.length() != s2.length()) {
        throw new IllegalArgumentException();
    }
    return s1.length();
}


This has the advantage that the method name is now self-documenting and it is returning the correct value, which means we can chain the result (just like requireNonNull which returns the non-null value or throws an exception).
import java.util.Optional; is not needed, you aren't using it.
Consider making the class final since it looks like a utility class (only public static methods).




If you're using Java 8, you could write this a bit shorter using the Stream API:

public static int compute(String s1, String s2) {
    int length = requireSameLength(s1, s2);
    return IntStream.range(0, length).map(i -&gt; s1.charAt(i) == s2.charAt(i) ? 0 : 1).sum();
}

private static int requireSameLength(String s1, String s2) {
    if (s1.length() != s2.length()) {
        throw new IllegalArgumentException();
    }
    return s1.length();
}


It maps each index to 0 or 1 based on whether the two input Strings have equal characters at that index, and sums the result.