Domanda

Non del tutto sicuro di come la parola a questa domanda. Mi chiedo se c'è un metodo per controllare alcune parti di una classe Java personalizzata per vedere se corrisponde a determinati criteri. Come questo

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

E poi, quando vengono creati una serie di istanze di quella classe dire,

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");

E 'possibile fare una ricerca sopra le istanze della classe per la persona con la

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

Io non vedo una soluzione che è if(surname.equals("bob")) then else, etc

Ma più di un in-built classe Java che permette una rapida ricerca sopra l'array. la velocità di questo è molto importante.

È stato utile?

Soluzione

Non c'è costruito in appoggio, ma Apache Collezioni e Google collezioni entrambi forniscono predicato sopra collezioni.

È possibile trovare questa domanda e le sue risposte utili. Stessa cosa con questo developer.com articolo.

es. Uso di Google Collezioni:

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));

Altri suggerimenti

La ricerca attraverso una matrice e "la velocità è molto importante" in realtà non vanno insieme. A meno che non se l'array sarà molto piccola, allora la ricerca attraverso una serie non sarà mai veloce. Questo è l'equivalente di una scansione completa della tabella in un database, le prestazioni non importa come si va su di esso sarà povera. La chiave per trovare rapidamente le cose è quello di utilizzare una struttura indicizzata. È ancora possibile avere una matrice se assolutamente bisogno, ma la ricerca dovrebbe essere fatto utilizzando un'altra struttura di dati. Estrarre un hash o di raccolta basato albero dal momento che organizzano i dati in un modo che lo rendono molto veloce per recuperare. TreeSet, TreeMap, HashSet, HashMap, ecc Hash i dati di indice su una chiave hash, alberi sono simili, ma anche memorizzare i loro dati in un modo ordinato.

Se avete bisogno di cercare in base alla parità di oggetto su assegno serie apache common ArrayUtils, Hai sostanzialmente ignorare i vostri pari e hascode per il nome oggetto e usarlo, ma se si desidera utilizzare criteri di ricerca personalizzati, immagino che devi implementare la tua strada e non c'è è costruito in supporto del linguaggio Java

Utilizzare un database memoria come Apache Derby o HSQLDB . Approfittate di JDBC, JPA o Hibernate, che tutti possono fare quello che vuoi.

Profilo codice. Poi ottimizzare.

Il modo più veloce che posso pensare, è quello di creare una struttura di dati che rispecchia questa oggetti valori delle proprietà e tenere l'indice interno per ogni valore ha.

Quando un valore viene cercato, questa struttura dati interna restituirà l'indice utilizzando ricerca binaria.

L'unico requisito è l'oggetto deve registrare e aggiornare questa struttura.

Qualcosa di simile al seguente immaginario UML / Python come codice:

 // 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

Spiacenti

Spero che questo è comprensibile.

Il punto è, se davvero cosa abbia questo veramente veloce, bisogna tenere gli indici dalla proprietà

  1. Un array per i dati
  2. Un array per ogni proprietà, che a sua volta ha l'indice di dati

Per esempio, se si ha la seguente matrice:

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

Avrebbero le posizioni:

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

E avrete due (in questo caso) array separati, che dopo essere stati ordinati sarebbe:

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

e

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

Quando si cerca un dato attributo, si prende l'array corrispondente, per esempio, se si wan per cercare il cognome "Reyes" Prenderai allineamento "Cognome"

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

E eseguirà binarySearch su di esso per "Reyes" che restituirà l'elemento in posizione 2, che a sua volta restituire l'indice = 1 whih è la posizione "Oscar" ha nell'array originale.

Questo dovrebbe mantenere le cose sotto O (log n)

Guardate classe ParallelArray, soddisfa le vostre esigenze, ma è necessario imparare un po 'di concetti di programmazione funzionale per utilizzare in modo efficiente.

La classe non viene fornito con JDK 6, ma potrebbe essere fornito con JDK 7 (in discussione). Nel frattempo è possibile utilizzarlo come una libreria - scaricare il pacchetto JSR166y da: http://gee.cs.oswego.edu/dl/concurrency-interest/

Si veda questo tutorial per una spiegazione dettagliata: http://www.ibm.com/developerworks/java/library/ j-jtp03048.html

Può sembrare complicato ed è (se vi arew solo di scavare in ad alte prestazioni di algoritmi multi-threaded). C'è un progetto Groovy che cerca di avvolgere un user-friendly API più in giro Array parallelo, quindi si potrebbe desiderare di ttake un'occhiata a questo articolo così: http://gpars.codehaus.org/ , http: // GPars. codehaus.org/Parallelizer

Java 8 aggiunto espressioni lambda e l'API flusso, quindi il supporto è built-in ora.

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));

Ci sono un sacco di opzioni disponibili qui. È possibile ottenere il nome da abbinare passando .findAny() a .findFirst() o eseguire la ricerca in parallelo con l'inserimento di .parallel() dopo .stream(applicants), per esempio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top