Frage

Nicht ganz sicher, wie man Wort dieser Frage. Ich frage mich, ob es eine Methode ist, bestimmte Teile einer benutzerdefinierten Java-Klasse zu überprüfen, um zu sehen, ob es ein bestimmten Kriterien übereinstimmt. wie dies Solche

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

Und dann, wenn eine Reihe von Instanzen dieser Klasse ist beispiel erstellt,

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

Ist es möglich, eine Suche über die Instanzen der Klasse für Person mit

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

Ich bin nicht wirklich auf der Suche nach einer Lösung, if(surname.equals("bob")) then else ist, etc

Aber noch eine eingebaute Java-Klasse, die für die schnelle Suche über das Array ermöglicht. Die Geschwindigkeit dieser ist sehr wichtig.

War es hilfreich?

Lösung

Es wird in Unterstützung nicht gebaut, aber Apache Sammlungen und Google Kollektionen bieten sowohl über Sammlungen Prädikats Unterstützung.

Sie können feststellen, diese Frage und seine Antworten hilfreich. Gleiche mit diesem developer.com Artikel.

z. Mit Google Kollektionen:

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

Andere Tipps

Die Suche in einem Array und „Geschwindigkeit ist sehr wichtig“, weiß wirklich nicht zusammen gehen. Es sei denn, wenn Ihr Array sehr klein sein wird dann durch eine Anordnung der Suche wird nie schnell sein. Dies ist das Äquivalent eines vollständigen Tabellenscan in einer Datenbank, Leistung, egal wie Sie es gehen wird schlecht. Der Schlüssel, um die Dinge schnell zu finden, ist eine indizierte Struktur zu verwenden. Sie können immer noch ein Array, wenn Sie unbedingt brauchen, aber die Suche sollte mit einer anderen Datenstruktur erfolgen. Überprüfen Sie einen Hash oder Baum basierte Sammlung aus, da sie Daten in einer Weise organisieren, dass es sehr schnell zu machen abzurufen. TreeSet, TreeMap, HashSet, HashMap usw. Hashes Indexdaten auf einem Hash-Schlüssel, Bäume sind ähnlich, aber auch in einer sortierten Reihenfolge ihre Daten speichern.

Wenn Sie auf das Objekt Gleichheit über Array-Check apache common ArrayUtils Suche müssen basiert, Sie müssen im Grunde Ihre Gleichen und hascode für Namensobjekt außer Kraft setzen und verwenden, aber wenn Sie benutzerdefinierte verwenden möchten Kriterien suchen, ich denke, Sie haben zu implementieren Ihr eigener Weg und es gibt keine in Java-Sprachunterstützung

gebaut

Verwenden Sie eine In-Memory-Datenbank wie Apache Derby oder hsqldb . Nutzen Sie den Vorteil von JDBC, JPA oder Hibernate, das kann alles tun, was Sie wollen.

Profil Code. Dann optimieren.

Der schnellere Weg ich mir vorstellen kann, ist eine Datenstruktur zu schaffen, die Spiegel dieser Objekte Eigenschaftswerte und halten Sie den internen Index für jeden Wert hat.

Wenn ein Wert gesucht wird, diese interne Datenstruktur wird über den Index binäre Suche zurückzukehren.

Die einzige Voraussetzung ist Ihr Objekt muss diese Struktur registrieren und aktualisieren.

So etwas wie die folgenden imaginäre UML / Python wie Code:

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

Oops

Ich hoffe, das ist verständlich.

Der Punkt ist, wenn Sie wirklich, was diese wirklich schnell zu haben, müssen Sie die Indizes halten durch Eigenschaft

  1. Ein Array für die Daten
  2. Ein Array für jede Eigenschaft, die wiederum den Index der Daten haben würde

Wenn Sie zum Beispiel die folgende Reihe:

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

Sie würden die Positionen haben:

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

Und Sie werden zwei haben (in diesem Fall) separate Arrays, die sortiert, nachdem sie wäre:

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

und

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

Wenn Sie für ein bestimmtes Attribut suchen, können Sie die entsprechenden Array nehmen, zum Beispiel, wenn Sie den Nachnamen „Reyes“ suchen wan Sie nehmen „nachName“ array

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

Und wird ausführen binarysearch darauf für „Reyes“, die das Element an der Position 2 zurück, was wiederum den Index = 1 zurück whih ist die Position „Oscar“ hat in der ursprünglichen Anordnung.

Das sollte die Dinge unter O (log n)

Schauen Sie sich ParallelArray Klasse, es erfüllt Ihre Anforderungen, aber Sie müssen ein wenig funktionalen Programmierung Konzepte lernen, sie effizient zu nutzen.

Die Klasse kommt nicht mit JDK 6, jedoch mit JDK 7 (in der Diskussion) kommen könnte. Inzwischen können Sie es als Bibliothek verwenden - laden Sie die JSR166y Paket aus: http://gee.cs.oswego.edu/dl/concurrency-interest/

Sehen Sie diese Anleitung für ausführliche Erläuterung: http://www.ibm.com/developerworks/java/library/ j-jtp03048.html

Es klingt vielleicht kompliziert, und es ist (wenn Sie nur im Bereich der Hochleistungs Graben Arew Algorithmen multi-threaded). Es gibt ein starkes Projekt, das eine benutzerfreundliche API um parallele Anordnung zu wickeln versucht, so dass Sie auch einen Blick auf sie ttake möchten: http://gpars.codehaus.org/ , http: // gpars. codehaus.org/Parallelizer

Java 8 hinzugefügt Lambda-Ausdrücke und die Stream-API, so dass die Unterstützung eingebaut ist jetzt.

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

Es gibt viele Optionen finden Sie hier. Sie können die Vornamen .findAny() zu .findFirst() entsprechen erhalten oder die Suche parallel laufen durch .parallel() nach .stream(applicants) Einfügen, beispielsweise durch Umschalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top