2016-10-30 13 views
5

Mam następujący:Tworzenie losowe wartości typu rodzajowego w Java

public class RandomList { 

    private List<Integer> list; 

    public List<Integer> getList() { 
     return list; 
    } 

    public RandomList (int n) { 
     list = new ArrayList<Integer>(); 

     Random rand = new Random(); 
     rand.setSeed(System.currentTimeMillis()); 

     for (int i=0; i < n; i++) 
     { 
      Integer r = rand.nextInt(); 
      list.add(r); 
     } 
    } 
} 

które daje mi listę wypełnioną losowych liczb całkowitych. Chciałbym to uogólnić, aby uzyskać listę losowych wartości Znaków lub list losowych wartości innych typów.

Więc to, czego chcę, to rodzajowy typ wersji, class RandomList<T>. Mogę zastąpić wszędzie "Integer" przez "T", ale utknąłem na linii Integer r = rand.nextInt();, która będzie czytać różne dla różnych typów.

Mam na myśli w następujący sposób:

  1. przepustkę w klasie typu rodzajowego do RandomList
  2. użyciu instanceof czek na przekazywane w klasie przeciwko pożądanych typów (Integer, Charakter ...) i w zależności od wyniku zwracana jest poprawna losowa wartość:

Czy to ma sens? Czy istnieje inny/lepszy sposób osiągnięcia tego, czego chcę?

Odpowiedz

6

Pierwsza metoda (gorszy)

W Javie nie można sprawdzić dla typu rodzajowego, przynajmniej nie bez refleksji. Jesteś na pieniądze z typu rodzajowego, więc chcesz zrobić coś takiego:

public class RandomList<T> { 
    private List<T> list; 
    private Class<T> clazz; 

    public List<T> getList() { 
     return list; 
    } 

    public RandomList (Class<T> clazz, int n) { 
     this.clazz = clazz; 
     list = new ArrayList<T>(); 

     Random rand = new Random(); 
     rand.setSeed(System.currentTimeMillis()); 

     if (clazz.isAssignableFrom(Integer.class)) { 
      for (int i = 0; i < n; i++) { 
       Integer r = rand.nextInt(); 
       list.add(r); 
      } 
     } 
     else { 
      throw new IllegalArgumentException("Unsupported class: " + clazz.getName()); 
     } 
    } 
} 

Druga metoda (Superior)

Alternatywnie, można uogólnić to jeszcze dalej i dodać Function produkować losowe wyniki. Zauważ, że wymaga to Java 8. Jeśli nie korzystasz z Java 8, możesz po prostu zdefiniować interfejs i skonstruować go anonimowo.

public class RandomList<T> { 
    private List<T> list; 

    public List<T> getList() { 
     return list; 
    } 

    public RandomList (Function<Random, T> creator, int n) { 
     list = new ArrayList<T>(); 

     Random rand = new Random(); 
     rand.setSeed(System.currentTimeMillis()); 

     for (int i = 0; i < n; i++) { 
      list.add(creator.apply(rand)); 
     } 
    } 
} 

konstruowania nowej instancji przy użyciu:

RandomList<Integer> list = new RandomList<>(rand -> rand.nextInt(), 10); 

Trzecia metoda (odkurzacz)

Edit: to dotarło do mnie później, ale to wydaje się być za pomocą Java 8, więc może po prostu użyć strumieni:

List<Integer> list = Stream.generate(() -> rand.nextInt()).limit(10).collect(Collectors.toList()) 
+1

Polecam tylko ** drugie ** podejście i eith er przedstawić pierwszą jako inną opcję (wątpliwą i budzącą wiele pytań) lub całkowicie ją usunąć. – Marco13

+0

Doskonały. Dziękuję Ci. Poszedłem z drugim podejściem (Function). – user1583209

+0

@ user1583209 Dodałem trzecią metodę, która jest znacznie czystsza. – KennethJ

Powiązane problemy