hash<string>() -- 函数对象

标准库的哈希函数

看C++Primer无序容器里面有一行代码,写法看上去有点陌生,学习记录一下。

size_t hasher(Const Sales_data &sd)
{
	return hash<string>() (sd.isbn());  //就是这行的写法
}

原文是这么描述的:
“hasher函数使用一个标准库hash类型对象来计算isbn的哈希值,该hash类型建立在string类型之上。”

仿函数

理解上面的语法,就先了解下仿函数,C++允许类重载函数调用运算符,这样的话,我们可以像使用函数一样使用该类。下面写一段测试代码来帮助理解上面那行对我来说看起来比较陌生(T^T)的写法。

#include <iostream>
using namespace std;

//定义一个对象
struct Hasher
{
public//默认构造函数
	Hasher()
	{
		cout << "Hasher default ctor" << endl;
	}
	//接受一个参数的构造函数
	Hasher(const char *str)
	{
		cout << "Hasher ctor:" << str << endl;
	}
	//重载函数调用运算符
	size_t operator() (const char *str) const
	{
		cout << "calling function:" << str << endl;
	}
}

int main(int argc, char *argv[])
{
	Hasher hasher("create obj");
	//下面这行对象调用了重载的函数运算符,就像调用函数一样
	//(类对象具有“像函数一样的行为”)
	hasher("testing  111"); 
	//仿照文章最开头那段代码 ---->hash<string>() ((sd.isbn))
	Hasher()("testing 222");
	return 0;
}

上面代码的运行结果:
在这里插入图片描述
结果显示的第三行和第四行就对应了:

Hasher()("testing 222");

调用默认构造函数先创建了一个临时的对象,然后再调用了重载函数,注意Hasher而不是hasher,C++允许直接通过类名+()来创建一个临时对象(既“Hasher()”),它只作用于当前行而已。

现在回头看开头那段代码就很好理解了。

如果你需要返回`List<User>`型的不同元素列表,你可以稍作修改代码。以下是修改后的示例: ```java import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; class User { private int id; private String name; public User(int id, String name) { this.id = id; this.name = name; } // getter和setter方法 // 重写equals()和hashCode()方法 @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof User)) { return false; } User other = (User) obj; return this.id == other.id && this.name.equals(other.name); } @Override public int hashCode() { return Objects.hash(id, name); } } public class Main { public static void main(String[] args) { // 创建两个列表 List<User> list1 = new ArrayList<>(); list1.add(new User(1, "Alice")); list1.add(new User(2, "Bob")); list1.add(new User(3, "Charlie")); List<User> list2 = new ArrayList<>(); list2.add(new User(2, "Bob")); list2.add(new User(3, "Charlie")); list2.add(new User(4, "David")); // 使用Stream API筛选不同的元素 List<User> differentElements = list1.stream() .filter(e -> !list2.contains(e)) .collect(Collectors.toList()); // 打印结果 System.out.println("不同的元素:" + differentElements); } } ``` 在这个示例中,我们修改了`User`,添加了构造函数、getter和setter方法。同时,重写了`equals()`和`hashCode()`方法来确保正确地比较`User`对象。 然后,我们使用Stream API的`filter`方法来筛选出在`list1`中存在但是在`list2`中不存在的用户,并将结果收集到一个新的`List<User>`中。 输出结果将是不同的用户列表,根据你的具体数据而定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值