时间:2017/5/15
作者:李国君
题目:快速查询List中指定的数据
背景:当List中保存了大量的数据时,用传统的方法去遍历指定的数据肯定会效率低下,有一个方法就是类似于数据库查询那样,根据索引直接提取数据。

     项目中遇到的软件卡顿的现象,其中一部分原因是因为数据量大的原因,所以有必要提高数据查询的速度。
     这里先展示一下模拟的的方法:假设List集合中有500000个点,每个点都有他的属性值xIndex(x坐标),yIndex(y坐标),text(描述),相当于10000*50的矩阵(10000列,50行),
(1,1)             (xIndex,yIndex) (2,1) (3,1) (。。。,。。。)
(1,2) (2,2) (3,2) (。。。,。。。)
(1,3) (2,3) (3,3) (。。。,。。。)
(。。。,。。。) (。。。,。。。) (。。。,。。。) (10000,50)
 
然后,当我们知道某一xIdex后,想要提取满足当前xIdex的所有行的数据(text属性值),先看效果:
从查询耗时对比可以看出鲜明的对比。
 

 
     方法介绍:
     1.传统的方法就是直接遍历List集合:
           //传统遍历
            var objPoints = from b in listPoints where b.xIndex == Convert.ToInt32(this.tbX.Text.Trim().ToString()) select b;
            foreach (var item in objPoints)
            {
                showPoints(item);     //显示当前点的text属性值;
            }
     这种遍历在数据量较少时很好用,简单明了,可是当数据量较大时,它的效率就会大打折扣,原因在于我们遍历了所有的数据,对我们没有用的数据也会逐个遍历,所以效率会降低。
     
     2.新方法是先将所有点的进行“归类”,将相同xIdex的点进行归类,归类的方法如下:
            hsTemp.Clear();//清空哈希表
            int TempCount = listPoints.Count;
            ; i < TempCount; i++)
            {
                if (hsTemp.ContainsKey(listPoints[i].xIndex.ToString()))//如果哈希表中存在key值
                {
                    hsTemp[listPoints[i].xIndex.ToString()] += "," + i.ToString();//这里和数组结构类似,改变索引值对应的value值信息
                }
                else
                {
                    hsTemp.Add(listPoints[i].xIndex.ToString(), i);
                }
            }
     然后,利用哈希表查询List中的数据,代码如下:
            this.richTextBox1.Text = "新方法查询结果:\n";
            //objPonit = new MyPoint();
            string currentPX = this.tbX.Text.Trim().ToString();
            if (listPoints != null && currentPX != null)
            {
                int TempCount = listPoints.Count;
                 && hsTemp.Count <= )//如果list中有数据而哈希表中却没有数据
                {
                    FlushTempIndex();
                }
                if (hsTemp.ContainsKey(currentPX))
                {
                    string[] arrTempIndex = hsTemp[currentPX].ToString().Split(',');//可以直接将分好的数据放到数组中去
                    int TempIndexCount = arrTempIndex.Length;
                    ;
                    ; i < TempIndexCount; i++)
                    {
                        if (int.TryParse(arrTempIndex[i], out TempIndex) && TempIndex < TempCount)
                        {
                            showPoints(listPoints[TempIndex]);
                        }
                    }
                }
            }
 

最后给出整个项目的代码:
1.首先创建一个实体类(点)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 快速查询数据.Models
{
    public class MyPoint
    {
        public int xIndex { get; set; }
        public int yIndex { get; set; }
        public string text { get; set; }
    }
}
2.创建好窗体应用程序,进行测试:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using 快速查询数据.Models;
using System.Collections;

namespace 快速查询数据
{
    public partial class Form1 : Form
    {
        List<MyPoint> listPoints = new List<MyPoint>();
        private Hashtable hsTemp = new Hashtable();
        MyPoint objPonit = null;
        public Form1()
        {
            InitializeComponent();
            this.tbY.Enabled = false;
            generaPoints();
        }
        //生成数据源
        private void generaPoints()
        {
            ;
             ; i <= ; i++)
            {
                ; j <= ; j++)
                {
                    objPonit = new MyPoint() { xIndex=i,yIndex=j,text=""+count};
                    count++;
                    listPoints.Add(objPonit);
                }
            }
        }
        //执行查询
        private void btQuery_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Text = null;
            DateTime beforDT = System.DateTime.Now;

            //耗时巨大的代码
            method2();

            DateTime afterDT = System.DateTime.Now;
            TimeSpan ts = afterDT.Subtract(beforDT);
            this.textBox1.Text = ts.TotalMilliseconds.ToString()+" ms";
        }
          //显示
        private void showPoints(MyPoint objMyPoint)
        {
            this.richTextBox1.Text += "," + objMyPoint.text;
        }
        /// <summary>
        /// LinQ查询
        /// </summary>
        private void method1()
        {
            this.richTextBox1.Text = "传统方法查询结果:\n";
            var objPoints = from b in listPoints where b.xIndex == Convert.ToInt32(this.tbX.Text.Trim().ToString()) select b;
            foreach (var item in objPoints)
            {
                showPoints(item);
            }
        }
        /// <summary>
        /// List和Hashtable集合查询
        /// </summary>
        private void method2()
        {
            this.richTextBox1.Text = "新方法查询结果:\n";
            //objPonit = new MyPoint();
            string currentPX = this.tbX.Text.Trim().ToString();
            if (listPoints != null && currentPX != null)
            {
                int TempCount = listPoints.Count;
                 && hsTemp.Count <= )//如果list中有数据而哈希表中却没有数据
                {
                    FlushTempIndex();
                }
                if (hsTemp.ContainsKey(currentPX))
                {
                    string[] arrTempIndex = hsTemp[currentPX].ToString().Split(',');//可以直接将分好的数据放到数组中去
                    int TempIndexCount = arrTempIndex.Length;
                    ;
                    ; i < TempIndexCount; i++)
                    {
                        if (int.TryParse(arrTempIndex[i], out TempIndex) && TempIndex < TempCount)
                        {
                            showPoints(listPoints[TempIndex]);
                        }
                    }
                }
            }
        }

        public void FlushTempIndex()
        {
            hsTemp.Clear();//清空哈希表
            int TempCount = listPoints.Count;
            ; i < TempCount; i++)
            {
                if (hsTemp.ContainsKey(listPoints[i].xIndex.ToString()))//如果哈希表中存在key值
                {
                    hsTemp[listPoints[i].xIndex.ToString()] += "," + i.ToString();//这里和数组结构类似,改变索引值对应的value值信息
                }
                else
                {
                    hsTemp.Add(listPoints[i].xIndex.ToString(), i);
                }
            }
        }

    }
}

快速查询List中指定的数据的更多相关文章

  1. mssql sqlserver 禁止删除数据表中指定行数据(转自:http://www.maomao365.com/?p=5323)

    转自:http://www.maomao365.com/?p=5323 摘要:下文主要讲述,如何禁止删除数据表中指定行数据 最近收到用户一个需求,禁止所有人删除”表A”中,ID 为1.2.3.4.5的 ...

  2. 每日学习心得:SharePoint 为列表中的文件夹添加子项(文件夹)、新增指定内容类型的子项、查询列表中指定的文件夹下的内容

    前言: 这里主要是针对列表中的文件下新增子项的操作,同时在新建子项时,可以为子项指定特定的内容类型,在某些时候需要查询指定的文件夹下的内容,针对这些场景都一一给力示例和说明,都是一些很小的知识点,希望 ...

  3. SQL查询显示行号、随机查询、取指定行数据

    转自:walkingp 1.显示行号 如果数据没有删除的情况下主键与行号是一致的,但在删除某些数据,行号就与主键不一致了,这时需要查询行号就需要用新的方法,在SQL Server2005之前,需要使用 ...

  4. 快速向表中插入大量数据Oracle中append与Nologging

    来源于:http://blog.sina.com.cn/s/blog_61cd89f60102e7gi.html 当需要对一个非常大的表INSERT的时候,会消耗非常多的资源,因为update表的时候 ...

  5. 用Spark查询HBase中的表数据

    java代码如下: package db.query; import org.apache.commons.logging.Log; import org.apache.commons.logging ...

  6. 【Linux】查询文件中指定字符串的记录

    语法 cat 文件 |grep 查询字符串 例如现在有文件file.dat,文件中内容如下: zhangsan Lisi wangwu123 wangwu890 zhangsan28290 现在想从文 ...

  7. Mysql快速删除表中重复的数据

    表结构 CREATE TABLE T_VENDOR ( ID ) NOT NULL AUTO_INCREMENT COMMENT 'ID', COUNTRY ) DEFAULT NULL COMMEN ...

  8. 超实用--删除MYSQL中指定的数据的全部表

    作过的人都知道,重复测试数据库的苦恼. 用法:# Usage: ./script user password dbnane mysql.nixcraft.in ~~~~~~~~~~~~~ #!/bin ...

  9. Java快速向数据库中插入大量数据 比如10万条以上

    String sql = "insert into table *****"; //必须要有这句,要不然效果不明显 con.setAutoCommit(false); ps = c ...

随机推荐

  1. javaWeb学习总结(3)- 通过Servlet生成验证码图片(2)

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:

  2. Nodejs进阶:核心模块Buffer常用API使用总结

    本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址.欢迎加群交流,群号 197339705. 模块概览 Buffer是node的核心模块,开发者可以利用它来处 ...

  3. laravel5.2之logout注销账号无效

    问题描述:laravel5.2的框架,使用框架auth用户认证后,进行账号注销退出的时候,无法实现. 只有清除浏览器缓存,才能实现账号退出. 解决办法: 改变路由 Route::get('auth/l ...

  4. 分布式版本控制git常见问题之gitignore冲突

    所见即所得,建议大家用可视化的SourceTree专为git打造的,非常好用,废话不多说了. 原因是有人提交了.gitignore里面的内容,所以和本地的不一样,这样就有问题,那么pull都不可以,所 ...

  5. CCNA毕业测试

    要求: 1:不同楼层物理隔离,但逻辑相连 2:相同楼层物理相连,但逻辑隔离 3:主机可以动态获取IP地址 4:不同VLAN间可以进行通信 5:主机最终访问www.baidu.com弹出Congratu ...

  6. mysql之 binlog维护详细解析(开启、binlog相关参数作用、mysqlbinlog解读、binlog删除)

    binary log 作用:主要实现三个重要的功能:用于复制,用于恢复,用于审计.binary log 相关参数:log_bin设置此参数表示启用binlog功能,并指定路径名称log_bin_ind ...

  7. Java经典编程题50道之一

    有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? public class Example01 {    publi ...

  8. 初识webpack——webpack四个基础概念

    前面的话 webpack是当下最热门的前端资源模块化管理和打包工具.它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源.当webpack处理应用程序时,它会递归地构建一个依赖关系图表 ...

  9. 浅谈JavaScript递归

    递归:是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现象.递归指的是一个过程:函数不断引用自身,直到引用的对象已知. //公园里面有200个桃子,每天吃掉一半,扔掉一个烂的,第6天 ...

  10. SQL Server各个版本的区别

    SQLEXPR_x64_CHS.exe,标准SQL Server Express edition,只有数据库引擎,甚至连图形管理界面都没有.SQLEXPRWT_x64_CHS.exe,多了一个图形管理 ...