当前位置: 首页 > 知识库问答 >
问题:

按排序顺序存储条目并检索条目周围的条目

云焱
2023-03-14

Position是排行榜中的位置,1是得分最高的用户

public class EntryTreeMapOption {

private String uid;
private int score;
private int position;

public EntryTreeMapOption(String uid, int score) {

    this.uid = uid;
    this.score = score;

}

public EntryTreeMapOption() {

}

public String getUid() {
    return uid;
}

public void setUid(String uid) {
    this.uid = uid;
}

public int getScore() {
    return score;
}

public void setScore(int score) {
    this.score = score;
}

public int getPosition() {
    return position;
}

public void setPosition(int position) {
    this.position = position;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((uid == null) ? 0 : uid.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    EntryTreeMapOption other = (EntryTreeMapOption) obj;
    if (uid == null) {
        if (other.uid != null)
            return false;
    } else if (!uid.equals(other.uid))
        return false;
    return true;
}

@Override
public String toString() {
    return "Entry [uid=" + uid + ", score=" + score + ", position=" + position + "]";
}}

GameBoard类有两个方法:

  • submitScore(String uid,int score)每个玩家调用这个方法将他的分数提交到游戏板上。每个玩家/用户只有一个条目,因此,如果玩家多次调用此方法,则存储其最新得分
  • GetLeaderBoard(字符串uid)
The leader board is :
Entry [uid=user1, score=14, position=1]
Entry [uid=user2, score=8, position=2]
Entry [uid=user3, score=7, position=3]
Entry [uid=user4, score=7, position=3]
Entry [uid=user5, score=4, position=4]
Entry [uid=user6, score=3, position=5]
Entry [uid=user7, score=3, position=5]
Entry [uid=user8, score=1, position=6]

For user5, entries returned should be :
Entry [uid=user3, score=7, position=3]
Entry [uid=user4, score=7, position=3]
Entry [uid=user5, score=4, position=4]
Entry [uid=user6, score=3, position=5]
Entry [uid=user7, score=3, position=5]

For user4, entries returned should be :
Entry [uid=user1, score=14, position=1]
Entry [uid=user2, score=8, position=2]
Entry [uid=user4, score=7, position=3]
Entry [uid=user5, score=4, position=4]
Entry [uid=user6, score=3, position=5]

For user6, entries returned should be :
Entry [uid=user4, score=7, position=3]
Entry [uid=user5, score=4, position=4]
Entry [uid=user6, score=3, position=5]
Entry [uid=user8, score=1, position=6]

For user7, entries returned should be :

Entry [uid=user4, score=7, position=3]
Entry [uid=user5, score=4, position=4]
Entry [uid=user7, score=3, position=5]
Entry [uid=user8, score=1, position=6]
public class GameDefault2 {

    private TreeMap<EntryMapOption, String> leaderBoardEntryUserMap;

    {

        leaderBoardEntryUserMap = new TreeMap<>(Comparator.comparingInt(EntryTreeMapOption::getScore).reversed()
            .thenComparing(EntryTreeMapOption::getUid));
    }

    @Override
    public void submitScore(String uid, int score) {

        EntryMapOption newEntry = new EntryMapOption(uid, score);
        leaderBoardEntryUserMap.put(newEntry, uid);

    }

    @Override
    public List<EntryMapOption> getLeaderBoard(String uid) {

        System.out.println("---------Current leader board---------");
        leaderBoardEntryUserMap.keySet().forEach(System.out::println);

        List<EntryMapOption> userEntryList = leaderBoardEntryUserMap.entrySet().stream()
                .filter(entry -> uid.equalsIgnoreCase(entry.getKey().getUid())).map(Map.Entry::getKey)
                .collect(Collectors.toList());

        if (userEntryList == null || userEntryList.isEmpty())
            return Collections.emptyList();

        // Incomplete and error prone
        EntryMapOption userEntry = userEntryList.get(0);

        List<EntryMapOption> entriesOptionTwo = new ArrayList<>();
        entriesOptionTwo.add(leaderBoardEntryUserMap.higherKey(userEntry));
        entriesOptionTwo.add(userEntry);
        entriesOptionTwo.add(leaderBoardEntryUserMap.lowerKey(userEntry));

        return entriesOptionTwo;

    }

}

上述代码的问题:

  • 何时(理想情况下,在submitScore()期间)以及如何计算“位置”。虽然map.compute()用于键,但我想知道它是否可以在任何方面提供帮助!
  • 检查“//不完整且易出错”注释下面的代码虽然“高键()”和“低键()”很有用,但我不确定如何使用它们来选择特定条目下面和上面的固定数量的条目

*****edit-1*******@Holger的修复解决了以下问题

    null

共有1个答案

奚曦哲
2023-03-14

您的equals方法基于ID,但您的compare方法基于score,这会引起Javadoc的问题。

请注意,如果要正确实现map接口,则树映射所维护的顺序(与任何排序映射一样)以及无论是否提供显式比较器,都必须与equals一致。(关于一致等于的精确定义,请参见Comparable或Comparator。)这是因为Map接口是根据equals操作定义的,但排序后的Map使用其compareTo(或compare)方法执行所有键比较,因此从排序后的Map的观点来看,该方法认为相等的两个键是相等的。一个排序映射的行为是很好定义的,即使它的排序与Equals不一致;它只是没有遵守Map接口的通用契约。

问题是,compare方法在对不同属性排序时,会将搜索带向错误的方向。

在您的情况下,这可能是一个较少的问题,尽管您可能有两个相等的对象,但没有相同的分数,导致未来的问题。

当项目在树中时更改得分也可能会引起问题,因此每次项目得分更改时您可能必须删除该项目,然后重新添加它们。

该过程的一个工作示例如下

import java.util.Comparator;
import java.util.TreeMap;

public class Test {

  static class Example {
    final int id;
    final int score;

    Example(int id, int score) {
      this.id = id;
      this.score = score;
    }

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof Example)) {
        return false;
      }
      final Example other = (Example) obj;
      return other.id == id;
    }

    @Override
    public int hashCode() {
      return id;
    }

    public int getId() {
      return id;
    }

    @Override
    public String toString() {
      return id + " scored " + score;
    }

    public int getScore() {
      return score;
    }
  }

  public static void main(final String... args) {
    Example a = new Example(1, 10);
    Example b = new Example(2, 30);
    Example c = new Example(3, 1);
    Example d = new Example(4, 10);

    TreeMap<Example, Integer> x = new TreeMap<Example, Integer>(Comparator.comparingInt(Example::getScore).thenComparing(Example::getId));

    x.put(a, a.getScore());
    x.put(b, b.getScore());
    x.put(c, c.getScore());
    x.put(d, d.getScore());

    final Example h2 = x.higherKey(a);
    final Example h1 = h2 == null ? null : x.higherKey(h2);

    final Example l1 = x.lowerKey(a);
    final Example l2 = l1 == null ? null : x.lowerKey(l1);

    System.out.println(h1);
    System.out.println(h2);
    System.out.println(a);
    System.out.println(l1);
    System.out.println(l2);
  }
}
 类似资料:
  • 波乔即是。java表示排行榜中的一个条目。Position是排行榜中的位置,1是得分最高的用户 . 我不知道该用什么谓词来返回5个条目,包括正在搜索的条目。另一个方面是性能,因为排行榜可以有几十万个条目。 *********编辑-1*********** 使用parallelStream()会导致问题吗? 列表条目=LeaderBoardUserEntryMap.EntrySet().Parall

  • 本文向大家介绍使用JavaScript按顺序检索对象的条目?,包括了使用JavaScript按顺序检索对象的条目?的使用技巧和注意事项,需要的朋友参考一下 假设以下是我们的对象- 使用方法按顺序检索对象的条目- 示例 要运行以上程序,您需要使用以下命令- 输出结果 在这里,我的文件名为demo146.js。这将产生以下输出-

  • 这是对这个问题的跟进。我有一个如下的查询: 当我这样做时,我会为用户获取不同的值,并且它们按asc顺序按角色\u id排序,此查询的唯一问题是具有两个或更多角色的用户位于仅具有一个角色的用户的后面。例如,用户有和的角色,而其他用户只有一个的角色,该用户将在列表中有两个角色的用户之前。我想改变这一点,让拥有更多角色的用户超过只有一个角色的用户。

  • 我在Firebase实时数据库中使用Unity创建了一个简单的排行榜: 键对应于用户名,值对应于用户分数。 我想 检索前20条记录 按分数排序时,检索给定用户名周围的5条记录(上面2条,本身和下面2条)。 我通过以下查询检索到前100名的分数: 我使用LimitToLast是因为排序是按升序进行的。 结果看起来像: 然后对于第二个任务,我想检索用户名周围的分数,比如“test100”。我想检索这样

  • 问题内容: 我有一个列表,其中每个元素都是形式。例如,列表的元素可能看起来像这样。 我想通过以下条件对包含描述的元素类型的列表进行排序: 如果两个元素的整数列表(即)的长度不同,则整数列表较小的元素是较小的元素。 否则,如果整数列表的长度相同,则较小的元素是第一个整数的较小整数,这两个元素的整数列表都不同。例如: [[1,1,99,100],-1] <[[1,1,100,1],-1],因为99 <

  • 如果我试图在不调用构造函数的情况下创建映射,则该对象不可用: 出于好奇,我想知道条目存储在哪里,但构造函数似乎没有添加属性: 你知道吗?