/** 对用户性别进行过滤 */
  public static void filterGender(
      long uid, RecommenderBuilder recommenderBuilder, DataModel dataModel, String gender)
      throws TasteException, IOException {
    Set<Long> userids = getByGender("datafile/book/user.csv", gender);

    // 计算指定性别用户打分过的图书
    Set<Long> bookids = new HashSet<Long>();
    for (long uids : userids) {
      LongPrimitiveIterator iter = dataModel.getItemIDsFromUser(uids).iterator();
      while (iter.hasNext()) {
        long bookid = iter.next();
        bookids.add(bookid);
      }
    }

    IDRescorer rescorer = new FilterRescorer(bookids);
    List<RecommendedItem> list =
        recommenderBuilder.buildRecommender(dataModel).recommend(uid, RECOMMENDER_NUM, rescorer);
    RecommendFactory.showItems(uid, list, false);
  }
  /**
   * Creates a new {@link GenericDataModel} from the given users (and their preferences). This
   * {@link DataModel} retains all this information in memory and is effectively immutable.
   *
   * @param userData users to include
   * @param timestamps optionally, provided timestamps of preferences as milliseconds since the
   *     epoch. User IDs are mapped to maps of item IDs to Long timestamps.
   */
  public GenericBooleanPrefDataModel(
      FastByIDMap<FastIDSet> userData, FastByIDMap<FastByIDMap<Long>> timestamps) {
    Preconditions.checkArgument(userData != null, "userData is null");

    this.preferenceFromUsers = userData;
    this.preferenceForItems = new FastByIDMap<>();
    FastIDSet itemIDSet = new FastIDSet();
    for (Map.Entry<Long, FastIDSet> entry : preferenceFromUsers.entrySet()) {
      long userID = entry.getKey();
      FastIDSet itemIDs = entry.getValue();
      itemIDSet.addAll(itemIDs);
      LongPrimitiveIterator it = itemIDs.iterator();
      while (it.hasNext()) {
        long itemID = it.nextLong();
        FastIDSet userIDs = preferenceForItems.get(itemID);
        if (userIDs == null) {
          userIDs = new FastIDSet(2);
          preferenceForItems.put(itemID, userIDs);
        }
        userIDs.add(userID);
      }
    }

    this.itemIDs = itemIDSet.toArray();
    itemIDSet = null; // Might help GC -- this is big
    Arrays.sort(itemIDs);

    this.userIDs = new long[userData.size()];
    int i = 0;
    LongPrimitiveIterator it = userData.keySetIterator();
    while (it.hasNext()) {
      userIDs[i++] = it.next();
    }
    Arrays.sort(userIDs);

    this.timestamps = timestamps;
  }