2015-08-25 3 views
0

я вещь, у меня есть проблема дизайнаGeneric преобразования в Java

я получаю в качестве входного сигнала:

  • список: List<String> типа, например "java.lang.string" ...
  • строка данных

Я хочу проверить, если данные относятся к типу list.get(i) динамически

Чтобы быть более ясным:

я получаю из базы данных списка в виде следующей list= {"java.lang.String", 'java.lang.Integer"}

и я получаю String данных «123». Я хочу проверить, что данные являются экземпляром list.get(1). Мой список и мои данные являются динамическими и могут меняться.

+1

Вы можете использовать Список

+3

Что именно вам нужно подтвердить? «Данные имеют тип list.get (i)», неясно. – RealSkeptic

+0

Итак, ваш список - это список строк, которые являются именами классов, таких как 'java.lang.String'? – RealSkeptic

ответ

2

Во время выполнения, список не типа List<String>, что видны только на уровне расчетов статических типов и относится к статическому типу выражений, не динамический типа экземпляров.

Во время выполнения список некоторого типа, реализующего List (скажем, ArrayList) и он просто содержит объектов того или иного типа. Тип может быть любым.

Таким образом, способ сделать ваш общий чек должен основываться на отражении. Вам нужно будет получить класс на Class.forName(String), а затем используйте Class.isInstance(Object), чтобы проверить, является ли объект этого типа.

+0

Я думаю, что размышление - хорошая идея. Но я все равно должен указать описание каждого типа в списке. Итак, если однажды я получу новый тип, мне придется изменить код. – Zizo

0

Допустим, у вас есть что-то вроде List<Object>, почему бы не преобразовать это в класс со списком для каждого типа в вашем исходном списке, например.

class HeapsOfLists { 

List<String> strings; 
List<Float> floats; 
List<Double> doubles;//.. ect 
} 

Просто сортировать все экземпляры в их по списку, может даже сделать хорошую маленькую группу по классу в новых ява потоков, или instanceof т.д .. Но это только мои 2cents. В других языках программирования у вас есть сопоставление параметров, которое построено для такого рода вещей (вроде). Это никогда не будет очень достойным, если у вас разные типы в одной коллекции, и тогда вам нужно спросить каждого парня, эй, черт возьми!

Вам всегда нужно добавить новый код для новых типов, и именно поэтому существуют интерфейсы, чтобы остановить эту проблему. Это похоже на цель, хотя! (Это не то, что java - плохой язык). Это значит, что jvm может работать быстрее и лучше оптимизировать код!

Мне всегда нравится думать о java как о слое поверх языка, ближе к компьютерному оборудованию, но не слишком далеко, как python или что-то в этом роде! Таким образом, вы все равно можете писать код, который очень быстро!

0

Можно ли принять метод boolean isValueOfType(String value, String className)?

  • assertTrue(isValueOfType("123", "java.lang.Integer"))
  • assertFalse(isValueOfType("ABC", "java.lang.Integer"))?

Я не вижу никакого способа достижения этой проверки без кода, применяемого к классу, как предложено выше Марко.

Вы можете достичь этого достаточно просто с картой функций, которые пытаются и преобразовывают value к типу: -

import java.util.HashMap; 
import java.util.Map; 
import java.util.function.Function; 

public class Converters { 
    private final Map<String, Function<String, Boolean>> converters; 

    Converters() { 
     converters = new HashMap<>(); 
     converters.put("java.lang.String", (v) -> true); 
     converters.put("java.lang.Integer", (v) -> { 
      try { 
       Integer.valueOf(v); 
       return true; 
      } 
      catch (NumberFormatException e) { 
       return false; 
      } 
     }); 
    } 

    public boolean isValueOfType(String value, String className) { 
     Function<String, Boolean> converter = converters.get(className); 
     return converter.apply(value); 
    } 
} 

И блок-тест

import org.junit.Assert; 
import org.junit.Test; 

public class ConvertersTest { 
    @Test 
    public void testInteger() { 
     Converters converters = new Converters(); 
     Assert.assertTrue(converters.isValueOfType("123", "java.lang.Integer")); 
     Assert.assertFalse(converters.isValueOfType("ABC", "java.lang.Integer")); 
    } 

    @Test 
    public void testString() { 
     Converters converters = new Converters(); 
     Assert.assertTrue(converters.isValueOfType("123", "java.lang.String")); 
     Assert.assertTrue(converters.isValueOfType("ABC", "java.lang.String")); 
    } 
} 

выше, может быть избыточна, но в основном таблицу поиска типов и соответствующих методов конвертера.

Если вы не можете использовать Java 8 (lambdas), то с обычными интерфейсами можно добиться чего-то подобного.

+0

Конечно, вы можете заменить карту конструкцией 'switch (className)' –

Смежные вопросы