Przypisywanie zmiennych z dynamicznymi nazwami w Javie

96

Chciałbym przypisać zestaw zmiennych w java w następujący sposób:

int n1,n2,n3;

for(int i=1;i<4;i++)
{
    n<i> = 5;
}

Jak mogę to osiągnąć w Javie?

Ashish Anand
źródło
1
Czy mógłbyś wyjaśnić swoje pytanie?
Eng.Fouad
4
Musisz to zrobić dla zmiennych lokalnych? Dlaczego nie macierz elementów?
Ray Toal,
@ Eng.Fouad: Chcę dynamicznie uzyskiwać dostęp do zmiennych według ich nazw.
Ashish Anand,
@Ashish Anand, czy masz na
myśli

Odpowiedzi:

111

To nie jest sposób, w jaki robisz rzeczy w Javie. W Javie nie ma zmiennych dynamicznych. Zmienne Java należy zadeklarować w kodzie źródłowym 1 .

W zależności od tego, co chcesz osiągnąć, powinieneś użyć tablicy, a Listlub a Map; na przykład

int n[] = new int[3];
for (int i = 0; i < 3; i++) {
    n[i] = 5;
}

List<Integer> n = new ArrayList<Integer>();
for (int i = 1; i < 4; i++) {
    n.add(5);
}

Map<String, Integer> n = new HashMap<String, Integer>();
for (int i = 1; i < 4; i++) {
    n.put("n" + i, 5);
}

Możliwe jest użycie odbicia, aby dynamicznie odwoływać się do zmiennych, które zostały zadeklarowane w kodzie źródłowym. Jednak działa to tylko w przypadku zmiennych, które są członkami klasy (tj. Pól statycznych i instancji). Nie działa dla zmiennych lokalnych. Zobacz przykład „szybki i brudny” @ fyr.

Jednak robienie tego rodzaju rzeczy niepotrzebnie w Javie to zły pomysł. Jest nieefektywny, kod jest bardziej skomplikowany, a ponieważ polegasz na sprawdzaniu w czasie wykonywania, jest bardziej delikatny. I to nie są „zmienne z dynamicznymi nazwami”. Lepiej jest to opisać jako dynamiczny dostęp do zmiennych o statycznych nazwach.


1 - To oświadczenie jest nieco nieścisłe. Jeśli używasz BCEL lub ASM, możesz „zadeklarować” zmienne w pliku kodu bajtowego. Ale nie rób tego! W ten sposób leży szaleństwo!

Stephen C.
źródło
1
Wielkie dzięki, dostałem to, czego szukałem. Ostatnia część (Map <String, integer>).
Ashish Anand,
1
Należy zauważyć, że nawet gdyby było to możliwe, nie powinno to być coś, co faktycznie byś zrobił. Nic z tego nie zyskujesz; faktycznie stracisz czytelność. Jeśli chcesz je połączyć, użyj Map<String, T>zamiast tego, nie zaczynaj mieszać z rzeczywistym kodem.
Jeroen Vannevel
2
@JeroenVannevel - To właśnie miałem na myśli przez „szaleństwo” :-)
Stephen C
35

Jeśli chcesz uzyskać dostęp do zmiennych w jakiś sposób dynamiczny, możesz użyć odbicia. Jednak odbicie nie działa dla zmiennych lokalnych. Ma zastosowanie tylko do atrybutów klas.

Prosty, szybki i brudny przykład:

public class T {
    public Integer n1;
    public Integer n2;
    public Integer n3;

    public void accessAttributes() throws IllegalArgumentException, SecurityException, IllegalAccessException,
            NoSuchFieldException {

        for (int i = 1; i < 4; i++) {
            T.class.getField("n" + i).set(this, 5);
        }
    }
}

Musisz ulepszyć ten kod na różne sposoby, to tylko przykład. To również nie jest uważane za dobry kod.

fyr
źródło
3
Doskonałe, gdy trzeba przekonwertować czujnik event.values ​​[] systemu Android na zestaw zmiennych. event.values ​​[] może mieć długość od 1 do 6 i przydatne jest przekonwertowanie go, w moim przypadku dla organizowania json bez tablicy.
Farshid T
12

Potrzebujesz nazwy tablica. Chciałem napisać następujący kod:

int[] n = new int[4];

for(int i=1;i<4;i++)
{
    n[i] = 5;
}
AlexR
źródło
1
Nie chcę używać tablic. Chcę dynamicznie uzyskiwać dostęp do zmiennych (n1, n2, n3) w zależności od pewnych warunków.
Ashish Anand,
10

Należy użyć Listalbo arrayzamiast

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);

Lub

int[] arr  = new int[10];
arr[0]=1;
arr[1]=2;

Albo nawet lepiej

Map<String, Integer> map = new HashMap<String, Integer>();
map.put("n1", 1);
map.put("n2", 2);

//conditionally get 
map.get("n1");
Jigar Joshi
źródło
7

Dynamiczne nazwy zmiennych w Javie
Nie ma czegoś takiego.

W twoim przypadku możesz użyć tablicy:

int[] n = new int[3];
for() {
 n[i] = 5;
}

W przypadku bardziej ogólnych (name, value)par użyjMap<>

Op De Cirkel
źródło
4

Spróbuj w ten sposób:

    HashMap<String, Integer> hashMap = new HashMap();

    for (int i=1; i<=3; i++) {
        hashMap.put("n" + i, 5);
    }

źródło
4

Ty nie. Najbliższą rzeczą, jaką możesz zrobić, jest praca z Mapami, aby to zasymulować, lub zdefiniowanie własnych obiektów, którymi będziesz się zajmować.

Everton
źródło