我需要存储我已读取的文件中的数据,数据结构为:ip地址和id(1.10.186.214; 2812432),并且id可以具有多个ip。
这是我用来读取文件的代码。我使用Treemap userdb存储有关用户的信息。我还需要另一个映射来存储ID和IP。
use serde::{Deserialize, Deserializer};
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FooDocument {
// other fields...
#[serde(rename = "type")]
#[serde(deserialize_with = "foo_document_type_deserialize")]
doc_type: FooDocumentType,
}
fn foo_document_type_deserialize<'de, D>(deserializer: D) -> Result<FooDocumentType, D::Error>
where
D: Deserializer<'de>,
{
use self::FooDocumentType::*;
let s = String::deserialize(deserializer)?;
match s.as_str() {
"tir lim bom bom" => Ok(Var1),
"hgga;hghau" => Ok(Var2),
"hgueoqtyhit4t" => Ok(Var3),
"Text" | "Type not detected" | "---" => Ok(Unknown),
_ => Err(serde::de::Error::custom(format!(
"Unsupported foo document type '{}'",
s
))),
}
}
#[derive(Debug, Clone, Copy)]
pub enum FooDocumentType {
Unknown,
Var1,
Var2,
Var3,
}
我决定使用Hashmap id作为键,将ip设置为值。这是正确的方法吗?如果不是,还有哪些其他选择?
答案 0 :(得分:0)
您已经拥有IP地址所属的User
,建议您将其用作第二个数据结构的密钥:
Map<User, Set<InetAddress>> mappings = new HashMap<>();
(我在这里使用过InetAddress
,但是您可能已经为此使用了一个类?)
然后您可以查找或创建给定用户的IP地址集并添加新条目:
InetAddress address = InetAddress.getByName(ip);
mappings.computeIfAbsent(user, ignored -> new HashSet<>()).add(address);
您的代码还有其他一些可能的问题:
您将每一行分为四个部分,但是示例数据只有两个?
在声明一个用户可以有多个IP地址(这是第二个数据结构的关键点)时,您将为每个条目创建一个 new 用户。您想首先检查您是否已经在userdb
中拥有该用户,即:
final User user;
if(users.containsKey(id)) {
user = users.get(id);
}
else {
user = new User(id);
users.put(id, user);
}
(您可以在这里再次使用computeIfAbsent
方法来简化逻辑)。
如果您决定将其用作键,则您的User
类应正确实现hashCode
和equals
。替代方案1仅将用户ID作为密钥。备选方案2将Set<InetAddress>
移到User
类中,该类在逻辑上仍然存在。
最后,四次分界线并没有多大意义,我想这个练习无关紧要,但这是一个很好的习惯:final String[] parts = line.split(";"); String ip = parts[0]; ...