Java 打印/使用100万个节点

Java 打印/使用100万个节点,java,javafx-2,javafx,nodes,Java,Javafx 2,Javafx,Nodes,我正忙于在窗格上绘制节点的练习。我的第一个目标是使用100万个节点,然后将其增加到1500万个 我有一个自定义的对象图,我可以向这个对象添加边和节点。每个节点对象都有一个椭圆,我可以调用它并绘制它,而边对象也是如此。 目前,我有一个函数,为节点生成一个随机位置 我目前正在使用滚动窗格来启用围绕窗格的平移并查看所有节点 我认为使用hashmap是个好主意 Map<String, ArrayList<Node>> mapX = new HashMap<String, A

我正忙于在窗格上绘制节点的练习。我的第一个目标是使用100万个节点,然后将其增加到1500万个

我有一个自定义的对象图,我可以向这个对象添加边和节点。每个节点对象都有一个椭圆,我可以调用它并绘制它,而边对象也是如此。 目前,我有一个函数,为节点生成一个随机位置

我目前正在使用滚动窗格来启用围绕窗格的平移并查看所有节点

我认为使用hashmap是个好主意

Map<String, ArrayList<Node>> mapX = new HashMap<String, ArrayList<Node>>();
Map<String, ArrayList<Node>> mapY = new HashMap<String, ArrayList<Node>>();
Map mapX=newhashmap();
Map mapY=新的HashMap();
我使用以下代码向hashmap添加节点:

int  tempXFloor = (int)Math.floor(tempX);
ArrayList<Node> tempList = mapX.get(tempXFloor+"");
if(tempList == null){
tempList = new ArrayList<>();
}
tempList.add(node); 
mapX.put(tempXFloor+"",tempList);
inttempxfloor=(int)数学地板(tempX);
ArrayList templast=mapX.get(tempXFloor+“”);
if(templast==null){
templast=newarraylist();
}
添加(节点);
放置(tempXFloor+“”,圣殿骑士);
然后,当我平移时,我得到当前位置,将其落地并检查地图中是否存在条目。如果存在一个条目,我会将ArrayList中的所有节点添加到NodeSensScreen。 nodesOnScreen是一种ArrayList类型,我将在平移时将节点添加到该列表中,同样,屏幕外的节点也将从nodesOnScreen变量中删除

我只打印ArrayList NodesScreen中的节点


我希望能在这方面提供一些指导,以及如何处理这样的大数据结构。我是朝着正确的方向走,还是我错过了一个明显的“窍门”呢。

你想要的属于你的范畴

你所描述的是一种特殊形式的语言。通用版本与您的不同之处在于,每个箱子的大小可能超过1个单位,因此更适合不同分辨率的数据集。BIN通常适用于或多或少均匀分布的数据集,它的实现也非常简单。查找屏幕上的元素只需查找视口中的所有容器

如果您的数据集是非统一的,即存在紧密的束和较大的空白,您可能需要尝试类似的替代结构


此外,如果您使用的是哈希表或任何其他java容器,请通过将int装箱为整数(
Map
)来使用int,不要将其转换为字符串,因为字符串速度慢得多,占用的内存也多。

您可以尝试使用数据虚拟化和数据提供程序“动态”构建它。不要使用RAM来保存大数据。使用数据库查询。在那里实现列表类型和索引器,它将从数据库返回一个项目。

有几点需要考虑:

  • 你的节点有多复杂?如果它们只是点,你可以考虑把它们画在A上,并保存大量的记忆。对于更复杂的情况,您可能需要使用。无论采用哪种方式,您都可以节省事件处理程序、属性和其他数量较大的小事

  • 另一个重要问题是数据视图的相关性。若你们展示了一张地图或类似的东西,那个么用户只关心可见的部分。其余的数据可以存储在磁盘缓存中,只有20%的数据会很有用。所以,您可以相应地进行规划,并且只有可视部分才有真正的图形节点(并且可能为了用户体验而预加载一些调整后的部分)

  • “分而治之”的概念。即使您不想根据计划(2)限制用户视图,也不能总是需要1500万个节点。UI库中没有,恐怕没有足够大的监视器。因此,将数据拆分为多个段,并一次加载一个段。如果您需要在整个集合上执行任何类型的计算——不要使用节点,请使用最简单的实现,并在一些后台进程中执行计算

  • 现有的解决方案总是在做大事之前先进行调查。例如,有许多类似的缓存库,它们无缝地允许您仅在将数十亿个节点拆分为组后处理相关数据


  • 考虑细节的层次。你不可能在屏幕上看到15米不同的点(没有足够的像素使单个节点前景在背景上可见)。有两种详细等级方法可用:

    • 图形化:使用一个非常大的画布(比如,10M x 10M),一次绘制小瓷砖(比如,1K x 1K像素),然后缩小比例以合成最终图像(例如,1K x 1K->10 x 10,两次,允许将10M x 10M虚拟画布缩小为1K x 1K图像)

    • 语义:将节点束聚合为单个节点,并绘制束节点而不是单个节点。您可以在多个级别执行此操作。事实上,如果您计划绘制图形,这正是图形绘制算法在下面要做的事情(如果没有某种层次分解,任何图形绘制算法都无法在合理的时间内处理>50K个节点)


    在这两种情况下,您都会根据需要提供某种缩放和细节;主概览将仅用于平移和放大特定细节。某种类型的空间索引(四叉树是最常见的一种)将允许您从磁盘或辅助存储中快速检索磁贴。在语义缩放场景中,您将为每个节点添加“父”字段,构建一个巨大的节点树(外部序列化;除非您真的需要,否则不要在内存中加载15万个节点)。

    四叉树是的。空间索引是OP将加载的数据保持在最小值所需要的。感谢hashmap提示。我一定会实现垃圾箱的想法,并尝试将我不使用的垃圾箱存储在数据库中。我必须查看四叉树,看看我能用它们做些什么。我找到了Geo4j,一个基于图形的数据库。将我的所有节点存储在Geo4j数据库中,然后使用四叉树检查下一步需要哪些节点,这听起来像是个好主意吗?不确定是否需要一个图形