I have a class TypesHolder that has four properties which are each int values.  I want to identify how many unique combinations of values are in the four int variables, and then to give a count of how many instances of TypesHolder have each specific combination of the four integer variables.  How can I accomplish this in code?  My code attempt below is failing, with the failed results summarized at the end.  There must be a simpler way to do this correctly.  
Here is my TypesHolder class:  
public class TypesHolder {
private int with;
private int type;
private int reason1;
private int reason2;
    //getters and setters
}
To hold the unique combinations during analysis, I created the following TypesSummaryHolder class:  
public class TypesSummaryHolder {
private int with;
private int type;
private int reason1;
private int reason2;
    private int count;
    //getters and setters
}
I then created an ArrayList to store the 15000+ instances of TypesHolder and another ArrayList to store the TypesSummaryHolder objects who represent each of the unique combinations of width, type, reason1, and reason2 from the TypesHolder objects, along with a count variable for each of the unique combinations.  I wrote the following code to populate the ArrayList of TypesSummaryHolder objects along with their counts:  
@SuppressWarnings("null")
static void countCommunicationTypes(){
    int CommunicationWithNumber;int CommunicationTypeNumber;int CommunicationReasonNumber;
    int SecondReasonNumber;int counter = 0;
    ArrayList<EncounterTypesHolder> types = new ArrayList<EncounterTypesHolder>();
    ArrayList<EncounterTypesSummaryHolder> summaries = new ArrayList<EncounterTypesSummaryHolder>();
////////
    try {Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");}
    catch (ClassNotFoundException e1) {e1.printStackTrace();}
    Connection sourceConn = null;
    try {sourceConn = DriverManager.getConnection("jdbc:odbc:PIC_NEW_32");}
    catch (Exception e1) {e1.printStackTrace();}
    Statement st = null;
    try {st = sourceConn.createStatement();}
    catch (Exception e1) {  e1.printStackTrace();}
    ResultSet rest = null;
    try {
        rest = st.executeQuery("SELECT * FROM someTable");
        while (rest.next()) {
            CommunicationWithNumber = rest.getInt(3);
            CommunicationTypeNumber = rest.getInt(5);
            CommunicationReasonNumber = rest.getInt(6);
            SecondReasonNumber = rest.getInt(6);
            EncounterTypesHolder etype = new EncounterTypesHolder();
            etype.setWith(CommunicationWithNumber);
            etype.setType(CommunicationTypeNumber);
            etype.setReason1(CommunicationReasonNumber);
            etype.setReason2(SecondReasonNumber);
            if(!isDuplicateType(etype,types)){
                EncounterTypesSummaryHolder summaryholder = new EncounterTypesSummaryHolder();
                summaryholder.setWith(CommunicationWithNumber);
                summaryholder.setType(CommunicationTypeNumber);
                summaryholder.setReason1(CommunicationReasonNumber);
                summaryholder.setReason2(SecondReasonNumber);
                summaryholder.setCount(1);
                summaries.add(summaryholder);
            } else {
                EncounterTypesSummaryHolder summaryholder = new EncounterTypesSummaryHolder();
                summaryholder.setWith(etype.getWith());
                summaryholder.setType(etype.getType());
                summaryholder.setReason1(etype.getReason1());
                summaryholder.setReason2(etype.getReason2());
                if(isDuplicateSummaryType(summaryholder, summaries)){
                    for(int u = 0; u<summaries.size();u++){
                        if((CommunicationWithNumber==summaries.get(u).getWith()) && (CommunicationTypeNumber==summaries.get(u).getType()) && (CommunicationReasonNumber==summaries.get(u).getReason1()) && (SecondReasonNumber==summaries.get(u).getReason2()) ){
                            int oldcount = summaries.get(u).getCount();
                            int newcount = oldcount+1;
                            summaries.get(u).setCount(newcount);
                        }
                    }
                }else {
                    summaryholder.setCount(1);
                    summaries.add(summaryholder);
                }
            }
            types.add(etype);
            counter += 1;
            System.out.println("counter is: "+counter);
            System.out.println("summaries.size() is: "+summaries.size());
        }
    } catch (Exception e) {e.printStackTrace();}
    System.out.println("at end: counter is: "+counter);
    System.out.println("at end: types.size() is: "+types.size());
    System.out.println("at end: summaries.size() is: "+summaries.size());
    int total = 0;
    for(int r=0;r<summaries.size();r++){
        total += summaries.get(r).getCount();
        int with = summaries.get(r).getWith();int type = summaries.get(r).getType();int reason1 = summaries.get(r).getReason1();int reason2 = summaries.get(r).getReason2();int thiscount = summaries.get(r).getCount();
    }
    System.out.println("total is: "+total);
}
static boolean isDuplicateType(EncounterTypesHolder testType, ArrayList<EncounterTypesHolder> types){
    for(int j = 0; j<types.size(); j++){
        if( (testType.getWith() == types.get(j).getWith()) && (testType.getType() == types.get(j).getType())  && (testType.getReason1() == types.get(j).getReason1()) && (testType.getReason2() == types.get(j).getReason2())){
            System.out.println("=====TRUE!!====");
            return true;
        }
    }
    return false;
}
static boolean isDuplicateSummaryType(EncounterTypesSummaryHolder testType, ArrayList<EncounterTypesSummaryHolder> types){
        for(int j = 0; j<types.size(); j++){
            if( (testType.getWith() == types.get(j).getWith()) && (testType.getType() == types.get(j).getType())  && (testType.getReason1() == types.get(j).getReason1()) && (testType.getReason2() == types.get(j).getReason2())){
                System.out.println("=====TRUE!!====");
                return true;
            }
        }
        return false;
}   
The code above is producing the following SYSO output at the end:
at end: counter is: 15415
at end: types.size() is: 15415
at end: summaries.size() is: 15084
total is: 2343089  
The max possible value for summaries.size() should be around 600, but the 331 you get from types.size() minus summaries.size() above is within the range of believable values for summaries.size().  However, the value for total should be equal to the 15414 value of types.size().  What is wrong with my code above?  How can I change my code above to get both a list of the unique combinations of with, type, reason1, and reason2, and also a count of the number of instances with each of those unique value combinations?
 
     
    