2012-12-10 7 views
5

chciałbym wiedzieć, w jaki sposób (jeśli to możliwe) mogę zaprogramować klasy Java przy użyciu układu danych Array of Class, na przykład:Jak automatycznie przekonwertować z Array z klasy do klasy tablic

public class X{ 

    double a; 
    double b; 
    double c; 
} 

public X array_of_x[SIZE] = new X [SIZE]; 

ale wewnętrznie dane byłyby przechowywać jako układ Class of Arrays jak ten:

public class X{ 

    double a[] = new double [SIZE]; 
    double b[] = new double [SIZE]; 
    double c[] = new double [SIZE]; 
} 

public X class_x = new X(); 

Moim celem jest to, że programista mógłby zaprogramowana w sposób bardziej intuicyjny stylu jak pierwszy, ale wewnętrzny zrobiłbym transformacje więc dane mogą być ciągłe w pamięci, a ja bym to zrobił osiągnąć większą wydajność.

Czy istnieje sposób na zrobienie tego, aby mógł zaakceptować dowolną klasę z pierwszym typem struktury i móc ją przekonwertować na drugie podejście? (lub jakiekolwiek narzędzie, które jest w stanie dokonać tego typu transformacji).

+1

Robię to bardzo często, ale zawsze robię to ręcznie. Byłoby interesujące usłyszeć, co mówią inni. (+1) – NPE

+4

Nie ma sposobu, aby to zrobić, ale dlaczego uważasz, że będzie to szybsze w stopniu wpływającym na wydajność? –

+1

@MiserableVariable: Lepsza lokalizacja odniesienia i bardziej zwarta reprezentacja. Bardzo dużo profilowałem takie rzeczy, aw wielu przypadkach nie ma konkursu. – NPE

Odpowiedz

3

Stwórzmy interfejs, który będzie wyświetlał pierwszy układ do wykorzystania i implementację dla tego interfejsu, który wewnętrznie wykorzystuje drugi układ. (Modyfikatory dostępu usuwane z kodem.)

interface X { 
    double getA(); 
    double getB(); 
    double getC(); 
}; 

interface ArrayOfX { 
    X get(int index); 
}; 

class ContiguousArrayOfX implements ArrayOfX { 
    class ContiguousX implements X { 
     int index; 
     ContiguousX(int index) { 
      this.index = index; } 
     double getA() { return a[index]; } 
     double getB() { return b[index]; } 
     double getC() { return c[index]; } 
    } 

    X get(int index) { 
     return new ContiguousX(index); } 

    double a[] = new double [SIZE]; 
    double b[] = new double [SIZE]; 
    double c[] = new double [SIZE]; 
}; 

Jeśli chcesz zmniejszyć obciążenie na GC, można także buforować wszystkie instancje ContiguousX. To zależy w dużej mierze od umiejętności kompilatora JIT, jeśli obiekty ContiguousX są w ogóle przydzielane do sterty - mogą one żyć w stosie, w tym przypadku narzut jest nieistotny. W ostateczności, można określić alternatywny interfejs dla szybkiego dostępu:

interface FasterArrayOfX { 
    double getA(int index); 
    double getB(int index); 
    double getC(int index); 
}; 

class FasterContiguousArrayOfX extends ContiguousArrayOfX implements FasterArrayOfX { 
    // Exercise left to the reader 
}; 

Poprzez programowanie przeciwko interfejs Zawsze możesz wybrać przechowywanie później.

Bardzo proste jest napisanie generatora kodu dla dowolnego układu klas. Powyższy kod może być użyty jako podstawa, tylko deklaracja metody i tablicy zależy od układu klas, który chcesz uzyskać. Nie znam żadnego istniejącego narzędzia.

+0

To wygląda ładnie, używałem AspectJ do przechwytywania getów i zestawów i zastępowania ich wykonywania dla innych pobiera i ustawia, które uzyskują dostęp do tablicy, ale twój sposób wygląda czystsze. – dreamcrash

+0

@dreamcrash: Chcesz podzielić się swoją implementacją? – krlmlr

+0

Chciałbym pokazać, ale to nie moja własność, wiesz, problemy z kontraktem – dreamcrash

Powiązane problemy