Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing MATLAB structs in Java objects

I'm using Java HashMap in MATLAB

h = java.util.HashMap;

And while strings, arrays and matrices works seemlessly with it

h.put(5, 'test');

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

Structs do not

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

??? No method 'put' with matching signature found for class 'java.util.HashMap'.




What would be the easiest/most elegant way to make it work for structs?

like image 405
Dani Avatar asked Jan 12 '09 20:01

Dani


2 Answers

You need to ensure that the data passed from MATLAB to Java can be properly converted. See MATLAB's External Interfaces document for the conversion matrix of which types get converted to which other types.

MATLAB treats most data as pass-by-value (with the exception of classes with handle semantics), and there doesn't appear to be a way to wrap a structure in a Java interface. But you could use another HashMap to act like a structure, and convert MATLAB structures to HashMaps (with an obvious warning for multiple-level structures, function handles, + other beasts that don't play well with the MATLAB/Java data conversion process).

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

a possible use case:

>> 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}

>>

(an exercise for the reader: change this to work recursively for structure members which themselves are structures)

like image 171
Jason S Avatar answered Sep 25 '22 21:09

Jason S


Matlab R2008b and newer have a containers.Map class that provides HashMap-like functionality on native Matlab datatypes, so they'll work with structs, cells, user-defined Matlab objects, and so on.

% 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
like image 43
Andrew Janke Avatar answered Sep 24 '22 21:09

Andrew Janke