2010-06-25 3 views
3

J'ai un objet java (appelons-le Foo) avec une méthode length().matlab: recherche d'une longueur d'un tableau d'objets Java

Dans MATLAB, je souhaite écrire une fonction qui accepte un tableau de ces objets et travaille avec. Mon problème est que la méthode habituelle d'écrire une boucle se décompose:

function doSomething(someArray) 
    for i = 1:length(someArray) 
     % do stuff with someArray(i) 
    end 

car dans ce cas Matlab décide « oh, c'est un objet Java, length(x) doit être interprétée comme x.length() car il a une méthode longueur():

function printLength(someArray) 
disp(length(someArray)); 

    ... 

> foo = %%% get my handle to the Java Foo object %%% 
> printLength([foo foo foo]) 
3 
> printLength([foo foo]) 
2 
> printLength([foo]) 
300000 
% foo.length() gets called and returns 300000 or whatever 

est-il un moyen de contourner ce problème?

+0

Je serais curieux de savoir si la «longueur» surchargée étaient appelées toutes les trois fois, ou seulement la troisième. Vous pouvez essayer d'utiliser [WHICH] (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/which.html) pour savoir quelle version de la fonction est appelée, comme 'quelle longueur d'impression ([ foo]) ',' printLength ([foo foo]) ', etc. – gnovice

+0

c'est vraiment seulement la 3ème fois. L'autre fois, vous avez un tableau de plus d'un objet, et MATLAB est assez intelligent pour savoir, oh, c'est un tableau, j'ai besoin de savoir la taille. –

Répondre

3

Vous pouvez utiliser builtin() pour forcer Matlab utilise ses propres fonctions length(), numel() ou autres, ignorant la méthode de la classe Java du même nom. L'appel de isscalar() ou numel() fonctionnera la plupart du temps, car les classes Java ont tendance à ne pas définir de méthodes avec ces noms. Mais si c'est le cas, vous obtiendrez la méthode Java et aurez le même problème qu'avec length(). L'utilisation de builtin() sera plus générale, quelle que soit la méthode utilisée par les classes Java.

>> foo = java.lang.String('foo'); 
>> builtin('length', [foo foo]) 
ans = 
    2 
>> builtin('length', [foo]) 
ans = 
    1 
>> length([foo]) 
ans = 
    3 
>> 

Vous pourriez envelopper comme ceci.

function out = mlength(x) 
%MLENGTH Array length, ignoring Java length() methods 

% Test for isjava to avoid ignoring overriden length() methods in Matlab objects 
if isjava(x) 
    out = builtin('length', x); 
else 
    out = length(x); 
end 
0

hmm, cela semble fonctionner ....

function printLength(someArray) 
if (isscalar(someArray)) 
    L = 1; 
else 
    L = length(someArray); 
end 
disp(L); 
1

Avez-vous essayé d'utiliser la fonction NUMEL au lieu de la fonction LENGTH? Cela devrait vous donner les mêmes résultats (c'est-à-dire le nombre d'éléments dans le tableau), mais évitez le problème avec la méthode surchargée length.

+0

Ou fonction «taille»? – yuk

+1

Vrai sur les deux. Je me demande s'il existe des méthodes réservées, ou si MATLAB distribue toujours aux objets Java s'il existe une méthode du nom en question. –

3

Vous pouvez utiliser une matrice de cellules au lieu d'un réseau régulier - cela fonctionnera:

>> jPanel = javax.swing.JPanel; 
>> length({jPanel,jPanel,jPanel}) 
ans = 
    3 
>> length({jPanel,jPanel}) 
ans = 
    2 
>> length({jPanel}) 
ans = 
    1 
>> length({}) 
ans = 
    0 

Et dans votre boucle, accédez simplement someArray{i} au lieu de someArray(i)