Java 检索ArrayList中与整数最接近的多个元素
我有一个由对象组成的ArrayList。在这些对象中,我有一个名为level的字段 我也有一个球员的水平。我试图检索最接近玩家级别的ArrayList中的元素,但前提是玩家级别高于对象中的级别 例如:Java 检索ArrayList中与整数最接近的多个元素,java,algorithm,arraylist,Java,Algorithm,Arraylist,我有一个由对象组成的ArrayList。在这些对象中,我有一个名为level的字段 我也有一个球员的水平。我试图检索最接近玩家级别的ArrayList中的元素,但前提是玩家级别高于对象中的级别 例如: static { foodSources = new ArrayList<FoodSource>(); foodSources.add(new FoodSource("foodSource1", 10)); foodSou
static {
foodSources = new ArrayList<FoodSource>();
foodSources.add(new FoodSource("foodSource1", 10));
foodSources.add(new FoodSource("foodSource2", 10));
foodSources.add(new FoodSource("foodSource3", 10));
foodSources.add(new FoodSource("foodSource4", 12));
foodSources.add(new FoodSource("foodSource5", 15));
foodSources.add(new FoodSource("foodSource6", 15));
foodSources.add(new FoodSource("foodSource7", 15));
foodSources.add(new FoodSource("foodSource8", 20));
foodSources.add(new FoodSource("foodSource9", 25));
}
如果玩家级别为10,它将检索foodSource1、foodSource2和foodSource3
如果玩家级别为11,它将检索foodSource1、foodSource2和foodSource3
但是,如果玩家级别为12,它将只检索foodSource 4
我正试图找到一种有效的方法来做这件事。我已经考虑过对ArrayList进行二进制搜索,但据我所知,您只能用它检索一个元素
大约一个半月前,我才重新开始编程,所以我不确定我可以在这里使用Java中的哪些功能
谢谢。正确的数据结构是树形图,它是一个二叉树 提供您要查找的信息 如果你不使用树形图,你将不得不满足于搜索
int toSearch = 11;
int min = Integer.MAX_VALUE;
List<FoodSource> found = new ArrayList<>();
for (FoodSource source : foodSources) {
int dist = Math.abs(toSearch - source.level);
if (dist < min) {
min = dist;
found.clear();
found.add(source);
} else if (dist == min) {
found.add(source)
}
}
这还将检索foodSource4,因为它是等距的,不确定您在该场景中想要什么行为执行此操作的正确数据结构是一个树映射,它是一个二叉树 提供您要查找的信息 如果你不使用树形图,你将不得不满足于搜索
int toSearch = 11;
int min = Integer.MAX_VALUE;
List<FoodSource> found = new ArrayList<>();
for (FoodSource source : foodSources) {
int dist = Math.abs(toSearch - source.level);
if (dist < min) {
min = dist;
found.clear();
found.add(source);
} else if (dist == min) {
found.add(source)
}
}
这还将检索食物来源4,因为它是等距的,不确定您在该场景中想要什么行为您可以创建一个映射levelToFoodSourceMap,在其中存储该级别的级别和可用食物来源之间的关系。此外,您还可以编写一个方法,该方法在给定级别的情况下返回与玩家级别最接近的较低级别,例如
int closestLowerLevel = findClosestLevel(12);
List<FoodSource> foodSources = levelToFoodSourceMap.get(closestLowerLevel);
地图的访问权限在中,findClosestLevel可能在Ologn中实现。您可以创建一个地图levelToFoodSourceMap,其中存储该级别的级别和可用食物源之间的关系。此外,您还可以编写一个方法,该方法在给定级别的情况下返回与玩家级别最接近的较低级别,例如
int closestLowerLevel = findClosestLevel(12);
List<FoodSource> foodSources = levelToFoodSourceMap.get(closestLowerLevel);
对地图的访问处于中,findClosestLevel可能在Ologn中实现。removeIf
你可以使用我写的这个函数,它是基于上面提到的。
该算法首先删除级别过高的对象,然后删除级别过低的对象,最后将生成一个包含所需对象的新ArrayList
密码
请注意,我是如何创建一个新的ArrayList以不修改原始ArrayList的。removeIf
你可以使用我写的这个函数,它是基于上面提到的。
该算法首先删除级别过高的对象,然后删除级别过低的对象,最后将生成一个包含所需对象的新ArrayList
密码
请注意我是如何创建一个新的ArrayList以不修改原始条目的。您可以使用二进制搜索来查找第一个条目,然后遍历列表以查找其余条目。TreeMap对此有很好的支持,但它只从一个键一个级别映射到一个值,因此您必须使用一个值列表
void append(TreeMap<Integer, List<FoodSource>> map, int level, FoodSource source) {
map.putIfAbsent(level, new ArrayList<>());
map.get(level).add(source);
}
TreeMap<Integer, List<FoodSource>> map = new TreeMap<>();
append(map, 10, new FoodSource("foodSource1", 10));
append(map, 10, new FoodSource("foodSource1", 10));
append(map, 12, new FoodSource("foodSource1", 12));
append(map, 15, new FoodSource("foodSource1", 15));
List<FoodSource> sources = map.floorKey(12).getValue();
然而,番石榴有一个树形图可以帮你处理这些。唯一的问题是,它将值保存在一个集合而不是一个列表中,因此在给定的级别上没有项目的顺序
TreeMultimap<Integer, FoodSource> map = TreeMultimap.create();
map.put(10, new FoodSource("foodSource1", 10));
map.put(10, new FoodSource("foodSource1", 10));
map.put(12, new FoodSource("foodSource1", 12));
map.put(15, new FoodSource("foodSource1", 15));
Set<FoodSource> sources = map.get(map.keySet().floor(12));
在每种情况下,floor都意味着获取小于或等于给定级别的最大键,并可以替换为天花以获取大于或等于给定级别的最小键。您可以使用二进制搜索来查找第一个条目,然后在列表中迭代以查找其余条目。TreeMap对此有很好的支持,但它只从一个键一个级别映射到一个值,因此您必须使用一个值列表
void append(TreeMap<Integer, List<FoodSource>> map, int level, FoodSource source) {
map.putIfAbsent(level, new ArrayList<>());
map.get(level).add(source);
}
TreeMap<Integer, List<FoodSource>> map = new TreeMap<>();
append(map, 10, new FoodSource("foodSource1", 10));
append(map, 10, new FoodSource("foodSource1", 10));
append(map, 12, new FoodSource("foodSource1", 12));
append(map, 15, new FoodSource("foodSource1", 15));
List<FoodSource> sources = map.floorKey(12).getValue();
TreeMultimap<Integer, FoodSource> map = TreeMultimap.create();
map.put(10, new FoodSource("foodSource1", 10));
map.put(10, new FoodSource("foodSource1", 10));
map.put(12, new FoodSource("foodSource1", 12));
map.put(15, new FoodSource("foodSource1", 15));
Set<FoodSource> sources = map.get(map.keySet().floor(12));
然而,番石榴有一个树形图可以帮你处理这些。唯一的问题是,它将值保存在一个集合而不是一个列表中,因此在给定的级别上没有项目的顺序
TreeMultimap<Integer, FoodSource> map = TreeMultimap.create();
map.put(10, new FoodSource("foodSource1", 10));
map.put(10, new FoodSource("foodSource1", 10));
map.put(12, new FoodSource("foodSource1", 12));
map.put(15, new FoodSource("foodSource1", 15));
Set<FoodSource> sources = map.get(map.keySet().floor(12));
在每种情况下,地板意味着获得小于或等于给定级别的最大关键点,可以用天花板替换,以获得大于或等于给定级别的最小关键点。在这种情况下,关键点是级别吗?@MarcelDoe就是这样。如果您不想切换数据结构,我还为您提供了一个快速的arraylist搜索算法;然后添加到树状图:foodsources.put15,level10Sources;对的这比一个Hashmap有什么好处?在这种情况下,关键是级别吗?@MarcelDoe就是这样。如果您不想切换数据结构,我还为您提供了一个快速的arraylist搜索算法;然后添加到
TreeMultimap<Integer, FoodSource> map = TreeMultimap.create();
map.put(10, new FoodSource("foodSource1", 10));
map.put(10, new FoodSource("foodSource1", 10));
map.put(12, new FoodSource("foodSource1", 12));
map.put(15, new FoodSource("foodSource1", 15));
Set<FoodSource> sources = map.get(map.keySet().floor(12));
TreeMap:foodsources.put15,level10Sources;对的与Hashmap相比,这有什么好处?对,我将使用级别作为键来导航地图-对吗?你能解释一下恒定时间吗?我在时间复杂性方面把一篇文章和恒定时间联系了起来。右键使用最近的标高导航地图。但是你仍然需要事先找到最近的关卡。TreeMap已经能够使用floorKey或ceilingKey找到最近的关卡。不要重新发明轮子。找到准确的数字是恒定的时间,而不是找到最接近的数字。@Rubydesic你是对的,我编辑了我的答案,并对你的答案进行了升级!对,我会用关卡作为导航地图的键-对吗?你能解释一下恒定时间吗?我在时间复杂性方面把一篇文章和恒定时间联系了起来。右键使用最近的标高导航地图。但是你仍然需要事先找到最近的关卡。TreeMap已经能够使用floorKey或ceilingKey找到最近的关卡。不要重新发明轮子。找到准确的数字是恒定的时间,而不是找到最接近的数字。@Rubydesic你是对的,我编辑了我的答案,并对你的答案进行了升级!