views:

1457

answers:

3

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?

+1  A: 

I'm not familiar with Java HashMaps, but could you try using a cell array to store the data instead of a struct?

h = java.util.HashMap;
carr = {7, 'hello'};
h.put(7, carr);

% OR

h = java.util.HashMap;
st.val = 7;
h.put(7, struct2cell(st));
gnovice
+3  A: 

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)

Jason S
+2  A: 

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
Andrew Janke