在Java对象中存储MATLAB结构体

8
我正在MATLAB中使用Java HashMap。
h = java.util.HashMap;

虽然字符串、数组和矩阵在此方面都运作得很顺畅。

h.put(5, 'test');

h.put(7, magic(4));

结构体不具备

h=java.util.HashMap;
st.val = 7;
h.put(7, st);

??? No method 'put' with matching signature found for class 'java.util.HashMap'.
如何以最简单/优雅的方式使其适用于结构体?
3个回答

7
你需要确保从MATLAB传递到Java的数据能够正确转换。请查看MATLAB的外部接口文档,了解哪些类型被转换为哪些其他类型的转换矩阵。
MATLAB将大多数数据视为按值传递(除了具有句柄语义的类),似乎没有一种方法可以将结构包装在Java接口中。但是,您可以使用另一个HashMap来充当结构,并将MATLAB结构转换为HashMaps(对于多级结构、函数句柄和其他不利于MATLAB/Java数据转换过程的东西,需要明显警告)。
function hmap = struct2hashmap(S)
if ((~isstruct(S)) || (numel(S) ~= 1))
    error('struct2hashmap:invalid','%s',...
          'struct2hashmap only accepts single structures');
end

hmap = java.util.HashMap;
for fn = fieldnames(S)'
    % fn iterates through the field names of S
    % fn is a 1x1 cell array
    fn = fn{1};
    hmap.put(fn,getfield(S,fn));
end

一个可能的使用案例:
>> M = java.util.HashMap;
>> M.put(1,'a');
>> M.put(2,33);
>> s = struct('a',37,'b',4,'c','bingo')

s = 

    a: 37
    b: 4
    c: 'bingo'

>> M.put(3,struct2hashmap(s));
>> M

M =

{3.0={a=37.0, c=bingo, b=4.0}, 1.0=a, 2.0=33.0}

>>

(读者的练习:将此改为递归地处理结构成员,这些成员本身是结构体)

5

Matlab R2008b及更高版本提供了一个containers.Map类,它在本地Matlab数据类型上提供了类似于HashMap的功能,因此它们可以与结构体、单元格、用户定义的Matlab对象等一起使用。

% Must initialize with a dummy value to allow numeric keys
m = containers.Map(0, 0, 'uniformValues',false);
% Remove dummy entry
m.remove(0);

m(5) = 'test';
m(7) = magic(4);
m(9) = struct('foo',42, 'bar',1:3);
m(5), m(7), m(9) % get values back out

但据我所知,它们似乎不适合作为Java Map<>参数的参数? - glglgl
正确,它们不是。这只是一个解决方案,如果您想使用所有Matlab数据类型而不是Java Map,并避免Java到Matlab转换的复杂性。如果您需要与接受Map的其他Java代码进行交互,这将无法工作。 - Andrew Janke

1
我不熟悉Java HashMaps,但你能否尝试使用单元数组来存储数据,而不是结构体?
h = java.util.HashMap;
carr = {7, 'hello'};
h.put(7, carr);

% OR

h = java.util.HashMap;
st.val = 7;
h.put(7, struct2cell(st));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接