Java 如何将类映射到散列,反之亦然

Java 如何将类映射到散列,反之亦然,java,ruby,Java,Ruby,我有一门课,像这样: class A attr_accessor(:field2) attr_accessor(:field1) end 用从类实例中获取的键和值生成散列的最佳方法是什么 用散列中的值填充类A实例的最佳方法是什么 ===== 我可能正在寻找类似于JavaBeans内省的东西,它会给我数据对象字段的名称,然后根据这些信息执行逻辑。Ruby是一种非常现代、灵活、动态的语言,我不承认它不会让我做我可以用Java轻松完成的事情;-) ===== 最后我发现Struct是最好的选

我有一门课,像这样:

class A
  attr_accessor(:field2)
  attr_accessor(:field1)
end
用从类实例中获取的键和值生成散列的最佳方法是什么

用散列中的值填充类A实例的最佳方法是什么

=====

我可能正在寻找类似于JavaBeans内省的东西,它会给我数据对象字段的名称,然后根据这些信息执行逻辑。Ruby是一种非常现代、灵活、动态的语言,我不承认它不会让我做我可以用Java轻松完成的事情;-)

=====

最后我发现Struct是最好的选择:

a = {:a => 'qwe', :b => 'asd'}

s = Struct.new(*a.keys).new(*a.values) # Struct from Hash

h = Hash[*s.members.zip(s.values).flatten] # Hash from Struct

开始玩的东西:

a = A.new
a.field1 = 1
a.field2 = 2
methods = a.public_methods(false).select { |s| s.end_with?("=") }
attributes = Hash[methods.map { |m| [m, a.send(m)] }]
=> {"field1"=>1, "field2"=>2}
如果您希望对pairs getter/setter进行更细粒度的检测:

methods = a.public_methods(false).group_by { |s| s.split("=")[0] }.
  map { |k, vs| k if vs.size == 2 }.compact
关于第二个问题:

attributes = {"field1"=>1, "field2"=>2}
a = A.new
a.each { |k, v| a.send(k+"=", v) }
=> #<A:0x7f9d7cad7bd8 @field1=1, @field2=2>
attributes={“field1”=>1,“field2”=>2}
新的
a、 每个{k,v{a.send(k+“=”,v)}

=>#或。

开始玩的东西:

a = A.new
a.field1 = 1
a.field2 = 2
methods = a.public_methods(false).select { |s| s.end_with?("=") }
attributes = Hash[methods.map { |m| [m, a.send(m)] }]
=> {"field1"=>1, "field2"=>2}
如果您希望对pairs getter/setter进行更细粒度的检测:

methods = a.public_methods(false).group_by { |s| s.split("=")[0] }.
  map { |k, vs| k if vs.size == 2 }.compact
关于第二个问题:

attributes = {"field1"=>1, "field2"=>2}
a = A.new
a.each { |k, v| a.send(k+"=", v) }
=> #<A:0x7f9d7cad7bd8 @field1=1, @field2=2>
attributes={“field1”=>1,“field2”=>2}
新的
a、 每个{k,v{a.send(k+“=”,v)}

=>#或。

类进行散列。当然,如果需要的话,可以将其作为方法写入

foo = A.new
foo.field1 = "foo"
foo.field2 = "bar"
hash = {}
foo.instance_variables.each {|var| hash[var.to_s.delete("@")] = foo.instance_variable_get(var) }
p hash
 => {"field1"=>"foo", "field2"=>"bar"} 
散列到类:扩展A的
初始化
。借来的

然后你可以:

hash = { :field1 => "hi" }
foo = A.new(hash)
 => #<A:0x00000002188c40 @field1="hi"> 
hash={:field1=>“hi”}
foo=A.new(散列)
=> # 

要散列的类。当然,如果需要的话,可以将其作为方法写入

foo = A.new
foo.field1 = "foo"
foo.field2 = "bar"
hash = {}
foo.instance_variables.each {|var| hash[var.to_s.delete("@")] = foo.instance_variable_get(var) }
p hash
 => {"field1"=>"foo", "field2"=>"bar"} 
散列到类:扩展A的
初始化
。借来的

然后你可以:

hash = { :field1 => "hi" }
foo = A.new(hash)
 => #<A:0x00000002188c40 @field1="hi"> 
hash={:field1=>“hi”}
foo=A.new(散列)
=> # 
尽管这在属性符号中给出了
@
;如果重要的话,你可以在作业中删掉它。反之亦然;迭代键并使用
实例变量集

您还可以询问以
=
结尾的方法,如果您向其中任何一个添加了逻辑,而不是依赖由
attr\u accessor创建的那些,那么这些方法将更加健壮

尽管这在属性符号中给出了
@
;如果重要的话,你可以在作业中删掉它。反之亦然;迭代键并使用
实例变量集



您还可以询问以
=
结尾的方法,如果您向其中任何一个添加了逻辑,而不是依赖由
attr_accessor创建的那些方法,那么这些方法将更加健壮。您必须在某个地方定义字段1和字段2是您感兴趣的字段,一个类有很多方法……是的,很多方法,但我对字段感兴趣,真的没有办法判断一个类中是否只有两个字段吗?类似于JavaBeans内省的东西?AFAIK attr_accessor透明地添加了getter/setter,因此您无法将它们与“普通”方法/实例变量区分开来。@Oleg可以,但如果您只对字段感兴趣,并且想要一个通用的解决方案,则不能依赖方法。Java中也是如此:getter可以在没有相应属性的情况下存在(并且通常通过JSP EL将数据公开给视图层),为什么不使用JSON或YAML并使用已经存在的东西呢?你必须在某个地方定义field1和field2是你感兴趣的字段,一个类有很多方法…是的,很多方法,但我对字段感兴趣,真的没有办法判断一个类中是否只有两个字段吗?类似于JavaBeans内省的东西?AFAIK attr_accessor透明地添加了getter/setter,因此您无法将它们与“普通”方法/实例变量区分开来。@Oleg可以,但如果您只对字段感兴趣,并且想要一个通用的解决方案,则不能依赖方法。Java中也是如此:getter可以在没有相应属性的情况下存在(并且通常通过JSP EL将数据公开给视图层)。我不确定您的最终目标是什么:如果是序列化/反序列化,为什么不使用JSON或YAML并使用已经存在的东西?这是一个合理的解决方案,虽然最终OP的实例变量会比attr_accessor创建的实例变量多。@tokland我不知道你是怎么知道的。对不起,我的意思是“可能有”,而不是“将有”,当然我不知道他的整个类是什么样子。Dave,我在你的回答中看到,你似乎更喜欢使用inject来构建散列而不是散列:[]。。。为什么?效率?@tokland With
[]
你要么需要一个映射、一个元组数组,要么需要一个平面有序数组——对于上面的内容,我发现
inject
Hash[f.instance_variables.collect{v,f.instance_variable_get(v)]稍微容易一些,即使注射的时间长了几个字符,但关闭时仍会让我的眼睛流泪。提醒你,也许还有更干净的方法;我没想过。这是一个合理的解决方案,尽管最终OP的实例变量会比attr_accessor创建的实例变量多。@tokland我不知道你是怎么知道的。对不起,我的意思是“可能有”,而不是“将有”,当然我不知道他的整个类是什么样子。一个问题,Dave,我在您的回答中看到,您似乎更喜欢使用inject来构建哈希而不是哈希::[。。。为什么?效率?@tokland With
[]
你要么需要一个映射、一个元组数组,要么需要一个平面有序数组——对于上面的内容,我发现
inject
Hash[f.instance_variables.collect{v,f.instance_variable_get(v)]稍微容易一些,即使注射的时间长了几个字符,但关闭时仍会让我的眼睛流泪。提醒你,也许还有更干净的方法;我还没想过。但是OpenStruct能让我得到它的值的哈希表示吗?是的,我可以使用OpenStruct.marshal_dump,OpenStruct是我真正需要的,谢谢!(希望不会太慢)是的,马什