Q:

How to leave only unique values in a List? - java

Basically, I have a model that stores two values int keyScore and List<Integer> moves. In the main class, I have a list of this model that is generated from calculation method. 
What I am trying to do is:

Concatenate List<Integer> moves if the keyScore equals
Remove duplicates

I tried to use HashSet on List<Integer> move, when I find equal keyScore, but I ended up with duplicates of my model. 
private class HeuristicResult {
        private int keyResult;
        private List<Integer> moves;

        private HeuristicResult(int keyResult, List<Integer> moves) {
            this.keyResult = keyResult;
            this.moves = moves;
        }

        private int getKeyResult(){
            return this.keyResult;
        }

        private List<Integer> getMoves(){
            return this.moves;
        }

        private void setMoves(List<Integer> moves){
            this.moves = moves;
        }

        @Override
        public String toString() {
            return String.format("%s : %s", this.keyResult, this.moves);
        }
    }
private List<HeuristicResult> concatHeuristicResults(List<HeuristicResult> heuristicResultsList){
            List<HeuristicResult> heuristicResults = heuristicResultsList;
            for(int i =0; i<heuristicResults.size()-2; i++){
                int score = heuristicResults.get(i).getKeyResult();
                for(int j = 0; j<heuristicResults.size()-1;j++){
                    if(score == heuristicResults.get(j).getKeyResult()){
                        heuristicResults.get(i).getMoves().addAll(heuristicResults.get(j).getMoves());
                        Set<Integer> temp = new HashSet<>(heuristicResults.get(i).getMoves());
                        heuristicResults.get(i).setMoves(new ArrayList<>(temp));
                    }
                }
            }
            return heuristicResults;
        }  

This is what I get as an output when I try to concatenate:
1 : [0, 1]
0 : [0, 1, 3, 6, 7, 8]
0 : [0, 1, 3, 6, 7, 8]
-10 : [3]
0 : [0, 1, 3, 6, 7, 8]
0 : [0, 1, 3, 6, 7, 8]
0 : [0, 1, 3, 6, 7, 8]
0 : [0, 1, 3, 6, 7, 8]
0 : [0, 1, 3, 6, 7, 8]
-1 : [0, 1, 7, 8]
0 : [0, 1, 3, 6, 7, 8]
0 : [0, 1, 3, 6, 7, 8]
0 : [0, 1, 3, 6, 7, 8]
-1 : [0, 1, 7, 8]
0 : [6]
0 : [6]

A:

Try this:
static Collection<HeuristicResult> concatenate(List<HeuristicResult> list) {
    HashMap<Integer, HeuristicResult> keys = new HashMap<>();

    for (HeuristicResult x: list) {
        HeuristicResult hr = keys.get(x.keyResult);

        if (hr != null) {
            // Merge hr and x.
            Set<Integer> moves = new HashSet<>();
            moves.addAll(hr.getMoves());
            moves.addAll(x.getMoves());

            hr.moves.clear();
            hr.moves.addAll(moves);
        }
        else {
            // Create a new entry into our keys map if it doesn't exist.
            keys.put(x.keyResult, x);
        }
    }
    return keys.values();
}

You're trying to merge hierarchically. First, you want unique keyResults and for each of these unique keyResults you want to merge moves. That's 2 levels of merging.
The HashMap (keyResult -> HeuristicResult) keeps only unique keyResults and maps them against the first HeuristicResult it sees in the list. Then during the iteration if it finds the same keyResult again, it pulls out the moves from the map and the one found in iteration and merges them. The merged Set is put back into the list (by clearing it first).

