I have the following code:
public class Porow{
    public static void main (String[] args){
        String s1 = "foo";
        String s2 = "foo";
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
        String s3 = new String ("foo");
        System.out.println(s1 == s3);
        System.out.println(s1.equals(s3));
    }
}
which outputs:
true
true
false
true
I am trying to understand and explain what's going on here. And I need some guidance. Will I be right to say s1 and s2 are same objects stored in different parts of memory and that's why we get the first 2 trues? 
Why is the 3rd output false? is s3 a different object? and why does it produce true with the equals method on s1? I'd appreciate some help. Thanks :).
EDIT: 
This question is not about == nor equals() I know what they are. My question is more related to memory references and addresses. So don't just presume I'm asking about String Comparison. I'm asking about a whole different thing here. 
 
     
     
     
     
    