public List<ID> getPreferredCoordinators(
      Set<ID> filter, ID localAddress,
      int maxNumberDesired) {
    List<ID> results = new ArrayList<>();
    List<ID> notPreferredCoordinatorList = new ArrayList<>();

    synchronized (membersLock) {
      for (ID addr : members) {
        if (addr.equals(localAddress)) {
          continue;// this is must to add
        }
        if (addr.preferredForCoordinator() && !filter.contains(addr)) {
          results.add(addr);
          if (results.size() >= maxNumberDesired) {
            break;
          }
        } else if (!filter.contains(addr)) {
          notPreferredCoordinatorList.add(addr);
        }
      }

      results.add(localAddress);// to add local address

      if (results.size() < maxNumberDesired && notPreferredCoordinatorList.size() > 0) {
        Iterator<ID> it = notPreferredCoordinatorList.iterator();
        while (it.hasNext() && results.size() < maxNumberDesired) {
          results.add(it.next());
        }
      }
    }

    return results;
  }
This functions returns the list of preferred coordinators. One random member from list of
non-preferred member list. It make sure that random member is not in suspected Set. And local
member.

@param filter Suspect member set.
@param localAddress the address of this member
@param maxNumberDesired number of preferred coordinators to return
@return list of preferred coordinators
geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSMembershipView.java