• C函数学习(2):GLib HashTable函数



    参考链接:
    1.源码
    https://gitlab.gnome.org/GNOME/glib/
    2.官网介绍
    https://docs.gtk.org/glib/struct.HashTable.html

    1 哈希表简介

    哈希表是一种基于key-value进行访问的数据结构,可以加快查找的速度,因此在一些需要快速查找是否有重复元素的场景中,常常使用哈希表来实现。

    2 Glib HashTable

    Glib提供了很多方便的功能,封装了我们经常使用的链表、数据结构等内容。本文简单介绍下Glib中哈希表相关的函数,方便以后使用。

    2.0 函数总览

    函数说明
    g_hash_table_new创建
    g_hash_table_new_full创建
    g_hash_table_new_similar创建
    g_hash_table_destroy删除全部key
    g_hash_table_remove删除指定key
    g_hash_table_remove_all删除全部key
    g_hash_table_steal从GHashTable中删除指定的key
    g_hash_table_steal_all从GHashTable中删除所有的key
    g_hash_table_steal_extended从GHashTable中删除指定的key
    g_hash_table_add添加
    g_hash_table_replace修改
    g_hash_table_insert插入
    g_hash_table_lookup查找key对应的value
    g_hash_table_lookup_extended查找key对应的value
    g_hash_table_find自定义查找规则进行查找
    g_hash_table_get_keys查找哈希表中的全部key
    g_hash_table_get_keys_as_array以数组的形式检索哈希表中的每个key
    g_hash_table_get_values查找哈希表中的全部value
    g_hash_table_foreach循环遍历哈希表中的每一个key/value
    g_hash_table_foreach_remove循环遍历哈希表中的每一个key/value,并删除符合func的key/value
    g_hash_table_foreach_steal循环遍历哈希表中的每一个key/value,并删除符合func的key/value
    g_hash_table_contains检查key是否存在于哈希表中
    g_hash_table_size哈希表中的key/value数量

    2.1 创建哈希表

    glib中提供了三个不同的函数用于创建哈希表:g_hash_table_new、g_hash_table_new_full、g_hash_table_new_similar。

    2.1.1 g_hash_table_new

    GHashTable *
    g_hash_table_new (GHashFunc  hash_func,
                      GEqualFunc key_equal_func);
    
    • 1
    • 2
    • 3

    创建一个引用计数为1的新HashTable。
    hash_func将key值转换为key_hash,一般使用g_str_hash函数来作为入参;
    key_equal_func用来比较key值,在插入,删除等操作时会调用此函数,一般使用g_str_equal函数来作为入参。

    2.1.2 g_hash_table_new_full

    GHashTable *
    g_hash_table_new_full (GHashFunc      hash_func,
                           GEqualFunc     key_equal_func,
                           GDestroyNotify key_destroy_func,
                           GDestroyNotify value_destroy_func);
                           
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    创建一个引用计数为1的新HashTable,并且允许指定函数来释放当GHashTable中删除条目时调用的key和value分配的内存。
    hash_func和key_equal_func的作用在上面已经介绍,不再赘述;
    key_destroy_func 是key值内存的释放,一般使用g_free函数来作为入参;
    value_destroy_func 是value值内存的释放。

    2.1.3 g_hash_table_new_similar

    GHashTable *
    g_hash_table_new_similar (GHashTable *other_hash_table);
    
    • 1
    • 2

    创建一个引用计数为1的新HashTable,其中hash_func、key_equal_func、key_destroy_func、 value_destroy_func等函数来自于other_hash_table。

    2.2 删除哈希表

    删除哈希表提供了几个不同的函数:g_hash_table_destroy、g_hash_table_remove、g_hash_table_remove_all。

    2.2.1 g_hash_table_destroy

    void
    g_hash_table_destroy (GHashTable *hash_table);
    
    • 1
    • 2

    销毁GHashTable中的所有的key和value。如果key和value是动态分配的,则需要先释放他们或者此函数会使用在创建时调用g_hash_table_new_full函数时候的key_destroy_func和value_destroy_func入参函数来自动销毁。

    2.2.2 g_hash_table_remove

    gboolean
    g_hash_table_remove (GHashTable    *hash_table,
                         gconstpointer  key);
    
    • 1
    • 2
    • 3

    从GHashTable中删除指定的key。如果key是动态分配的,则需要先释放内存或者此函数会使用在创建时调用g_hash_table_new_full函数时候的key_destroy_func和value_destroy_func入参函数来自动销毁。

    2.2.3 g_hash_table_remove_all

    void
    g_hash_table_remove_all (GHashTable *hash_table);
    
    • 1
    • 2

    从GHashTable中删除所有的key。如果key是动态分配的,则需要先释放内存或者此函数会使用在创建时调用g_hash_table_new_full函数时候的key_destroy_func和value_destroy_func入参函数来自动销毁。

    2.2.4 g_hash_table_steal

    gboolean
    g_hash_table_steal (GHashTable    *hash_table,
                        gconstpointer  key);
    
    • 1
    • 2
    • 3

    从GHashTable中删除指定的key。但是不会调用函数释放key/value内存。

    2.2.5 g_hash_table_steal_all

    void
    g_hash_table_steal_all (GHashTable *hash_table);
    从GHashTable中删除所有的key。但是不会调用函数释放key/value内存。

    2.2.6 g_hash_table_steal_extended

    gboolean
    g_hash_table_steal_extended (GHashTable    *hash_table,
                                 gconstpointer  lookup_key,
                                 gpointer      *stolen_key,
                                 gpointer      *stolen_value);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    从GHashTable中删除指定的key。但是不会调用函数释放key/value内存。同时会输出stolen_key、stolen_value表示查找到的key/value;

    2.3 添加

    添加哈希表提供了几个不同的函数:g_hash_table_add、g_hash_table_replace、g_hash_table_insert。

    2.3.1 g_hash_table_add

    gboolean
    g_hash_table_add (GHashTable *hash_table,
                      gpointer    key);
    
    • 1
    • 2
    • 3

    添加key,如果此key已经存在于哈希表中,则释放旧的key,使用新的key来覆盖。

    2.3.2 g_hash_table_replace

    gboolean
    g_hash_table_replace (GHashTable *hash_table,
                          gpointer    key,
                          gpointer    value);
    
    • 1
    • 2
    • 3
    • 4

    插入一个新的key和value到GHashTable中,如果有旧的key存在GHashTable中,则会被新的key替代,而旧的key和value则会被自动销毁,此函数会使用在创建时调用g_hash_table_new_full函数时候的key_destroy_func和value_destroy_func入参函数来自动销毁。

    2.3.3 g_hash_table_insert

    gboolean
    g_hash_table_insert (GHashTable *hash_table,
                         gpointer    key,
                         gpointer    value);
    
    • 1
    • 2
    • 3
    • 4

    插入一个新的key和value到GHashTable中,如果有旧的key存在,则value值会被覆盖为新的value值。

    2.4 查找

    glib中提供了几个不同的函数用于查找:g_hash_table_lookup_extended、g_hash_table_lookup、g_hash_table_find。

    2.4.1 g_hash_table_lookup

    gpointer
    g_hash_table_lookup (GHashTable    *hash_table,
                         gconstpointer  key);
    
    • 1
    • 2
    • 3

    在 GHashTable 中查找一个键。此函数无法区分不存在的key和key存在,但是vlaue为空这种情况,因为这两种情况返回值都为NULL。

    2.4.2 g_hash_table_lookup_extended

    gboolean
    g_hash_table_lookup_extended (GHashTable    *hash_table,
                                  gconstpointer  lookup_key,
                                  gpointer      *orig_key,
                                  gpointer      *value);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    orig_key为输出,即查找到的key;
    value为输出,即查找到的value;
    返回值为TRUE表示已经找到原始的key。

    2.4.3 g_hash_table_find

    gpointer
    g_hash_table_find (GHashTable *hash_table,
                       GHRFunc     predicate,
                       gpointer    user_data);
    
    • 1
    • 2
    • 3
    • 4

    根据用于自定义的查找规则函数predicate来进行查找,如果predicate返回TRUE,则表示查找到对应的key,则g_hash_table_find就会返回对应的value;如果predicate一直返回FALSE,则表示一直没有查找到。

    2.4.4 g_hash_table_get_keys

    GList *
    g_hash_table_get_keys (GHashTable *hash_table);
    
    • 1
    • 2

    查找哈希表中的全部key。

    2.4.5 g_hash_table_get_keys_as_array

    gpointer *
    g_hash_table_get_keys_as_array (GHashTable *hash_table,
                                    guint      *length);
    
    • 1
    • 2
    • 3

    以数组的形式检索哈希表中的每个key,length表示数组的长度。

    2.4.6 g_hash_table_get_values

    GList *
    g_hash_table_get_values (GHashTable *hash_table);
    
    • 1
    • 2

    查找哈希表中的全部key对应的value。

    2.5 遍历

    2.5.1 g_hash_table_foreach

    void
    g_hash_table_foreach (GHashTable *hash_table,
                          GHFunc      func,
                          gpointer    user_data);
    
    • 1
    • 2
    • 3
    • 4

    循环遍历哈希表中的每一个key/value。

    2.5.2 g_hash_table_foreach_remove

    guint
    g_hash_table_foreach_remove (GHashTable *hash_table,
                                 GHRFunc     func,
                                 gpointer    user_data);
    
    • 1
    • 2
    • 3
    • 4

    循环遍历哈希表中的每一个key/value,并删除符合func的key/value。符合即func返回TRUE,此函数再删除符合的key/value会使用在创建时调用g_hash_table_new_full函数时候的key_destroy_func和value_destroy_func入参函数来自动销毁。

    2.5.3 g_hash_table_foreach_steal

    guint
    g_hash_table_foreach_steal (GHashTable *hash_table,
                                GHRFunc     func,
                                gpointer    user_data);
    
    • 1
    • 2
    • 3
    • 4

    循环遍历哈希表中的每一个key/value,并删除符合func的key/value。符合即func返回TRUE,此函数不会调用函数释放key/value。

    3 示例

    一个简单的示例程序。

    #include 
    #include 
    #include 
    #include 
    
    static GHashTable *gpHash;
    
    
    void iterator(gpointer key, gpointer value ,gpointer user_data)
    {
    	printf("%s, key:%s, value:%s", user_data, key, value);
    }
    
    int main()
    {
    	//创建
    	gpHash = g_hash_table_new_full(g_str_hash, g_str_equal,
                                             g_free, NULL);
    	//插入
    	g_hash_table_insert(gpHash, "1","test1");
    	g_hash_table_insert(gpHash, "2","test2");
    	g_hash_table_insert(gpHash, "3","test3");
    	g_hash_table_insert(gpHash, "4","test4");
    	g_hash_table_insert(gpHash, "5","test5");
    	
    	//获取大小
    	printf("hash num:%d\n", ,g_hash_table_size(gpHash);
    	
    	//查找指定key对应的value
    	g_printf("key:%s, value:%s\n", "1", g_hash_table_lookup(gpHash, "1");
    	
    	//删除指定key
    	gboolean found = g_hash_table_remove(gpHash, "1");
    	g_printf("del:%s, state:%d\n", "1", found);
    	
    	//遍历全部的key
    	g_hash_table_foreach(gpHash, (GHFunc)iterator, "test");
    	
    	//删除全部key
    	g_hash_table_destroy(gpHash);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    C语言系统化精讲(四):C语言变量和数据类型-下篇
    如何使用在 10 分钟内构建您的 Flutter 新闻应用程序而无需编码(Nowa 教程)
    基于python的GUI设计
    神经网络和深度学习-加载数据集DataLoader
    前端架构-分层而治,铁打的MV流水的C
    总结Java 并发编程 72 变
    SpringMVC 程序开发
    易基因:鸡的chTERT靶基因DNA甲基化检测揭示ALV-J肿瘤发生机制|客户文章
    Seata四种事务模式AT、TCC、SAGA 、 XA详解
    Mac电脑卡顿的解决办法
  • 原文地址:https://blog.csdn.net/u011003120/article/details/125149417