Вопрос

Не совсем уверен, как сформулировать этот вопрос.Мне интересно, есть ли способ проверить определенные части пользовательского класса Java, чтобы увидеть, соответствует ли он определенным критериям.Такой как этот

public Name(String forename, String middlename, String surname)

И затем, когда будет создан массив экземпляров этого класса, скажем:

Name[] applicants = new Name[4];

applicants[0] = new Name("john","bob", "rush");
applicants[1] = new Name("joe","bob", "rushden");
applicants[2] = new Name("jack","bob", "rushden");
applicants[3] = new Name("jake","bob", "rushden");

Можно ли выполнить поиск по экземплярам класса для человека с

midddlename.equals("bob") && surname.equals("rush")

Я на самом деле не ищу решение, которое if(surname.equals("bob")) then else,и т. д

Но это скорее встроенный Java-класс, который позволяет осуществлять быстрый поиск по массиву.скорость этого очень важна.

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

Решение

Встроенной поддержки нет, но Коллекции Апачей и Коллекции Google оба обеспечивают поддержку Predicate для коллекций.

Вы можете найти этот вопрос и его ответы полезны.То же самое и с этим разработчик.com статья.

напримерИспользование коллекций Google:

final Predicate<name> bobRushPredicate = new Predicate<name>() {
   public boolean apply(name n) {
      return "bob".equals(n.getMiddlename()) && "rush".equal(n.getSurname());
   }
}

final List<name> results = Iterables.filter(applicants, bobRushPredicate));

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

Поиск по массиву и фраза «скорость очень важна» несовместимы.Если ваш массив не будет очень маленьким, поиск по массиву никогда не будет быстрым.Это эквивалент полного сканирования таблицы в базе данных, производительность, независимо от того, как вы это сделаете, будет низкой.Ключом к быстрому поиску вещей является использование индексированной структуры.У вас все еще может быть массив, если он вам абсолютно необходим, но поиск следует выполнять с использованием другой структуры данных.Обратите внимание на коллекции на основе хэша или дерева, поскольку они организуют данные таким образом, что их извлечение происходит очень быстро.TreeSet, TreeMap, HashSet, HashMap и т. д.Хэши индексируют данные по хешированному ключу. Деревья аналогичны, но также хранят свои данные в отсортированном порядке.

Если вам нужно искать на основе равенства объектов по проверке массива apache common ArrayUtils, По сути, вам нужно переопределить ваши равенства и hascode для объекта имени и использовать его, но если вы хотите использовать собственные критерии поиска, я думаю, вам придется реализовать свой собственный путь, и встроенная поддержка языка Java отсутствует.

Используйте базу данных в памяти, например Апач Дерби или hsqldb.Воспользуйтесь преимуществами JDBC, JPA или Hibernate, которые могут делать все, что вы хотите.

Профилируйте свой код.Тогда оптимизируйте.

Я могу придумать более быстрый способ — создать структуру данных, которая отражает значения свойств этого объекта и содержит внутренний индекс для каждого значения.

При поиске значения эта внутренняя структура данных возвращает индекс с использованием двоичного поиска.

Единственное требование — ваш объект должен зарегистрировать и обновить эту структуру.

Что-то вроде следующего воображаемого кода, подобного UML/Python:

 // Holds the index number of a given value
 // for instance, name="Oscar" may be at index 42...
 IndexValuePair
     index : Int
     value : String 

     +_ new( value: String, index: Int ) 
          return IndexValuePair( value, index )

 ValuePairComparator --> Comparator 

     + compareTo( a: IndexValuePair, b: IndexValuePair ) : Int 

         return a.value.compareTo( b.value )

 SearchStructure
     - data = Object[] // The original array which contains your applicants
      // a list of arrays each one containing the property value, and the index on "data" where that value appears 
     - dataIndexes =  List(IndexValuePair)[String] // Map<List<IndexValuePair>> 
     - dataIndexexInitialized = false

     // Add an object to this structure
     + addObject( o: Object ) 
          if( ! dataIndexesInitialized, 
              initIndexesWith( o )
          )

          index = data.add( o ) // returns the index at which "o" was inserted
          addToIndexes( o, index ) 

     // Register all the properties values of the given object 
     // along with the index where they appear in the original array 
     - addToIndexes( object: Object, index: Int ) 
           forEach( property in Object , 
              list = dataIndexes[property]
              list.add( IndexValuePair.new( property.value, index ) ) 
           )
     // Create empty array for each property .. 
     - initIndexesWith( object : Object ) 
          forEach( property in object , 
                comparator = ValuePairComparator()
                list = List<IndexValuePair>()
                list.setComparator(  ) 
                dataIndexes[property] =  list
          )
          dataIndexesInitialized = true 


     // Search an object using the given criteria ( a Map<String, String> = key=value ) 
     + search( criteria: String[String] ) : List<Object>

        result = Set<Object>()

        // let's say criteria has:
        // ["name":"Oscar", "lastName"="Reyes"]
       forEach( key in criteria, 
            list = dataIndexes[key]  // "name", "lastname" ..etc. 
            valuePair = list.binarySearch( criteria[key] ) // first Oscar, later Reyes 
            result.add( data[valuePair.index] )
       ) 

       return result

упс

Надеюсь, это понятно.

Дело в том, что если вы действительно хотите, чтобы это было действительно быстро, вам нужно хранить индексы по свойствам.

  1. Массив для данных
  2. Массив для каждого свойства, который, в свою очередь, будет иметь индекс данных.

Например, если у вас есть следующий массив:

 a = [ Object(name="Mike", lastName="Z" )
       Object(name="Oscar", lastName="Reyes" ) , 
       Object(name="Rahul", lastName="G" ) , 
       Object(name="Pie", lastName="154" )  ]

У них будут должности:

0 = Mike ... 
1 = Oscar ...
2 = Rahul ...
3 = Pie ...

И у вас будет два (в данном случае) отдельных массива, которые после сортировки будут иметь вид:

nameArray =  ["Mike=0", "Oscar=1", "Pie=3", "Rahul=2"]

и

lastNameArray =   ["154=3", "G=2", "Reyes=1", "Z=0"]

Когда вы ищете данный атрибут, вы берете соответствующий массив, например, если вы хотите найти фамилию «Рейес», вы возьмете массив «lastName».

 ["154=3", "G=2", "Reyes=1", "Z=0"]

И выполнит для него двоичный поиск «Рейеса», который вернет элемент в позиции 2, который, в свою очередь, вернет индекс = 1, который соответствует позиции «Оскара» в исходном массиве.

Это должно держать вещи под O (log n)

Посмотрите на класс ParallelArray, он удовлетворяет вашим требованиям, но вам нужно изучить некоторые концепции функционального программирования, чтобы эффективно его использовать.

Класс не поставляется с JDK 6, но может поставляться с JDK 7 (в стадии обсуждения).Тем временем вы можете использовать его как библиотеку — загрузите пакет JSR166y по адресу:http://gee.cs.oswego.edu/dl/concurrency-interest/

Подробное объяснение смотрите в этом уроке:http://www.ibm.com/developerworks/java/library/j-jtp03048.html

Это может показаться сложным, и это так (если вы просто копаетесь в высокопроизводительных многопоточных алгоритмах).Существует проект Groovy, который пытается обернуть более удобный для пользователя API вокруг Parallel Array, поэтому вы также можете взглянуть на него: http://gpars.codehaus.org/ , http://gpars.codehaus.org/Parallelizer

В Java 8 добавлены лямбда-выражения и потоковый API, поэтому поддержка теперь встроена.

Name[] applicants = new Name[4];

applicants[0] = new Name("john", "bob", "rush");
applicants[1] = new Name("joe", "bob", "rushden");
applicants[2] = new Name("jack", "bob", "rushden");
applicants[3] = new Name("jake", "bob", "rushden");

Optional<Name> result = Arrays.stream(applicants)
    .filter(name -> name.middlename.equals("bob") && name.surname.equals("rush"))
    .findAny();

result.ifPresent(name -> System.out.println(name));

Здесь есть много вариантов.Вы можете получить соответствующее имя, переключив .findAny() к .findFirst() или запустить поиск параллельно, вставив .parallel() после .stream(applicants), например.

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