способ инициализации javabean для случайных значений

StackOverflow https://stackoverflow.com/questions/838616

  •  22-07-2019
  •  | 
  •  

Вопрос

Я искал какой-нибудь служебный класс / код, который брал бы java bean и инициализировал все его значения случайными значениями.Это может быть сделано с помощью отражения, поскольку некоторые библиотеки уже создают методы toString() или equals().Это полезно при разработке пользовательского интерфейса, например, для получения некоторых данных.

Другие возможные приятные для имущих:

  1. рекурсивно инициализируйте также непримитивные или простые элементы (строка, дата)
  2. инициализировать коллекцию компонентов
  3. возможно, дайте какой-то способ ограничить генерируемые значения, например, для чисел мы могли бы указать диапазоны, для строк - регулярные выражения или подстановочные знаки...

кто-нибудь знает что-то подобное?Спасибо

Редактировать:разрешение...Образец Apocalisp заработал, и это окончательно то, что я искал.У этого есть некоторые недостатки, ИМХО:

  • Библиотека имеет гораздо большую область применения, чем это использование, но для меня это не проблема
  • Довольно сложно понять, как построить Произвольную для ваших объектов, если вы не потратите некоторое время на изучение всего этого.Это недостаток.
  • И, я думаю, это могло бы быть более лаконично, но это тоже прекрасно.

Спасибо!

Это было полезно?

Решение

Взгляните на Класс Gen из библиотеки Reductio.Это часть высоко настраиваемой платформы для создания произвольные значения более или менее любого типа.Предоставляются генераторы для примитивных типов и большинства классов Java collections.Вы должны уметь создавать Arbitrary экземпляры для ваших классов довольно легко.

Редактировать Вот пример, исправленный:

import static fj.test.Arbitrary.*;
import static fj.Function.*;

static final Arbitrary<Person> personArbitrary =
  arbitrary(arbInteger.gen.bind(arbString.gen, arbBoolean.gen,
      curry(new F3<Integer, String, Boolean, Person>() {
        public Person f(final Integer age, final String name, final Boolean male)
          {return new Person(age, name, male);}})));

Затем сгенерируйте произвольного пользователя "размера 100" вот так.То есть.его имя будет состоять не более чем из 100 символов.

Person p = personArbitrary.gen.gen(100, Rand.standard);

Другие советы

Взгляните на Случайные Бобы:

https://github.com/benas/random-beans

Это позволяет вам заполнить граф объектов Java случайными данными.

Надеюсь, это поможет

С наилучшими пожеланиями

Хотя я заметил, что этот пост, возможно, немного устарел, у меня просто возникла такая же необходимость, и ни одно из представленных решений, казалось, не решало ее приемлемым образом, поэтому я применил какой-то быстрый и грязный пятнадцатиминутный не совсем универсальный метод утилиты для генерации случайно заполненных компонентов, который может быть, а может и не быть полезным для кого-то еще, у кого случайно возникла подобная проблема:

import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Random;

import org.springframework.beans.BeanUtils;

public class RandomBeanUtil {

    public static <T> Collection<T> generateTestData(Class<T> clazz, int quantity) {
        Collection<T> list = new ArrayList<T>();

        PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(clazz);
        Random rand = new Random();

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        try {
            for (int i = 0; i != quantity; i++) {
                    T o = clazz.newInstance();

                    for (PropertyDescriptor descriptor : descriptors) {
                        Class<?> type = descriptor.getPropertyType();
                        if (String.class.isAssignableFrom(type)) {
                            descriptor.getWriteMethod().invoke(o, String.valueOf(new char[]{
                                    (char)('A' + rand.nextInt(26)), (char)('a' + rand.nextInt(26)) }));
                        } else if (Date.class.isAssignableFrom(type)) {
                            cal.add(Calendar.DATE, rand.nextInt(60) - 30);
                            descriptor.getWriteMethod().invoke(o, cal.getTime());
                        } else if (BigDecimal.class.isAssignableFrom(type)) {
                            descriptor.getWriteMethod().invoke(o, 
                                    new BigDecimal(rand.nextDouble() * 500).setScale(2, RoundingMode.HALF_UP));
                        }
                    }

                    list.add(o);
            }       
        } catch (Exception e) {
            // TODO: Improve exception handling
            throw new RuntimeException("Error while generating the bean collection", e);
        }

        return list;
    }

}

У меня нет библиотеки для вас, но если вы получите генератор случайных чисел, то, возможно, этот класс вам пригодится:

public class BeanMethodIterator implements Iterable<Method> {

    private static final int MODIFIER_FILTER = (Modifier.PUBLIC | Modifier.STATIC);
    private static final int MODIFIER_EXPECTED = Modifier.PUBLIC;

    /**
     * Indicator to filter getter or setter methods. 
     */
    public enum Filter {

        /** Only getter methods. */
        GETTERS(new Transform<Method, Boolean>(){
            public Boolean transform(Method input) {
                return (input.getName().startsWith("get") || 
                        input.getName().startsWith("is")) 
                    &&  input.getParameterTypes().length == 0;
            };
        }),

        /** Only setter methods. */
        SETTTERS(new Transform<Method, Boolean>(){
            public Boolean transform(Method input) {
                return input.getName().startsWith("set") && 
                    input.getParameterTypes().length == 1;
            };
        }),

        /** Getter and setter methods. */
        BOTH(new Transform<Method, Boolean>(){
            public Boolean transform(Method input) {
                return Filter.SETTTERS.condition.transform(input) || 
                    Filter.GETTERS.condition.transform(input);
            };
        });

        private Transform<Method, Boolean> condition;

        private Filter(Transform<Method, Boolean> condition) {
            this.condition = condition;
        }

    };

    /**
     * Iterate parent methods also?
     */
    public enum Scope {
        PARENTS_ALSO() {
            @Override
            protected Method[] getMethods(Class<?> c) {
                return c.getMethods();
            };
        },
        THIS_CLASS_ONLY() {
            @Override
            protected Method[] getMethods(Class<?> c) {
                return c.getDeclaredMethods();
            }
        };

        protected abstract Method[] getMethods(Class<?> c);
    }

    private final Filter filter;
    private final Scope scope;
    private final Class<?> theClass;

    /**
     * Constructor. 
     *
     * @param theClass
     * @param what
     */
    public BeanMethodIterator(Class<?> theClass, Filter what, Scope scope) {
        this.filter = what;
        this.theClass = theClass;
        this.scope = scope;
    }

    /**
     * Constructor. 
     */
    public BeanMethodIterator(Class<?> theClass) {
        this(theClass, Filter.BOTH, Scope.PARENTS_ALSO);
    }

    /**
     * Tells if a method is public
     * @param method
     * @return
     */
    private static boolean isPublic(Method method) {
        return (method.getModifiers() & MODIFIER_FILTER) == MODIFIER_EXPECTED; 
    }

    /**
     * {@inheritDoc}
     * @see java.lang.Iterable#iterator()
     */
    public Iterator<Method> iterator() {
        final Method[] methods = this.scope.getMethods(this.theClass);        

        return new Iterator<Method>() {
            int index = 0;

            public boolean hasNext() {
                while (index < methods.length) {
                    if (isPublic(methods[index]) && filter.condition.transform(methods[index]))
                        return true;
                    index++;
                }
                return false;
            }

            public Method next() {
                if (!hasNext())
                    throw new NoSuchElementException();
                return methods[index++];
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }

        };
    }

    public static void main(String[] args) {
        for (Method m: new BeanMethodIterator(Date.class, Filter.GETTERS, Scope.THIS_CLASS_ONLY)) {
            System.out.println(m.getName());
        }
    }

}


/**
 * Represents a function that takes one input and returns a transformation of that input value i.e.
 * a transformation. The name Transform is used because it is shorter.
 * 
 * @author Hannes de Jager
 * @since 01 Sep 2008
 */
interface Transform<I, O> {

    /**
     * Invokes the function, performing the transformation, to produce an interpreted value.
     * 
     * @param input the input value.
     * @return The computed result.
     */
    public O transform(I input);
}

Apache Commons BeanUtils (http://commons.apache.org/beanutils) может быть полезно для вас.Нет никакой утилиты, которую вы могли бы использовать готовый к использованию, но я предполагаю , что все строительные блоки есть , т. е.доступ к свойствам, генераторам случайных чисел.

Вы можете делать то, чего вы хотели бы достичь, с помощью Входные данные библиотека с открытым исходным кодом.Он использует определения диапазона на основе XML-дескрипторов, а не определения в коде.InPUT использует внедрение метода и конструктора, поддерживая сложные структуры объектов произвольной глубины инициализации. Примеры, и Руководства доступны.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top