public Map<Integer, List<LocationBean>> clusterFromArray( double[][] distanceArray, List<LocationBean> locations, double distance) { Map<Integer, List<LocationBean>> groupings = new HashMap<Integer, List<LocationBean>>(); int grouping = 1; for (LocationBean location : locations) { location.setGroup(0); } for (int x = 0; x < locations.size(); x++) { if (locations.get(x).getGroup() == 0) { while (groupings.containsKey(grouping)) { grouping++; } // System.out.println("Creating new group: " + grouping + " for point at " + x + " with name // " + locations.get(x).getName()); locations.get(x).setGroup(grouping); groupings.put(grouping, new ArrayList<LocationBean>()); groupings.get(grouping).add(locations.get(x)); } else { grouping = locations.get(x).getGroup(); } for (int y = 0; y < locations.size(); y++) { if (y > x) { // // avoid processing the duplicate half of the array if (distanceArray[x][y] <= distance) { if (locations.get(y).getGroup() == 0) { locations.get(y).setGroup(grouping); groupings.get(grouping).add(locations.get(y)); // System.out.print(" +" + locations.get(y).getName() + " "); } else if (locations.get(y).getGroup() == grouping) { //// do nothing? } else { // combine groups int otherGroup = locations.get(y).getGroup(); // System.out.println("Combining groups " + grouping + " (" + // groupings.get(grouping).size() + ") and " + otherGroup + "(" + // groupings.get(otherGroup).size() + ")"); int originalSize = groupings.get(grouping).size(); for (int i = 0; i < originalSize; i++) { // System.out.print(i + " "); groupings.get(otherGroup).add(groupings.get(grouping).remove(0)); } locations.get(x).setGroup(otherGroup); } } } } // System.out.println("Group " + grouping + " has size " + groupings.get(grouping).size()); } //// Prune empty groupings - not a necessary step, but helps clean up the result a bit. Set<Integer> keys = groupings.keySet(); int maxKey = 0; for (Integer key : keys) { // since there is no gaurantee about consecutive group numbers, we have to go // through all possible keys if (key > maxKey) maxKey = key; } for (int i = 1; i <= maxKey; i++) { if (groupings.containsKey(i) && groupings.get(i).size() == 0) { // System.out.println("removing group " + i); groupings.remove(i); } } return groupings; }