سؤال

لست متأكدًا تمامًا من كيفية صياغة هذا السؤال. أتساءل عما إذا كانت هناك طريقة للتحقق من أجزاء معينة من فئة 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 بنيت تسمح بالبحث السريع على المصفوفة. سرعة هذا مهمة جدا.

هل كانت مفيدة؟

المحلول

لم يتم تصميمه في الدعم ، ولكن مجموعات Apache و مجموعات جوجل كلاهما يوفر الدعم المسند على المجموعات.

قد تجد هذا السؤال وإجاباتها مفيدة. نفس الشيء مع هذا Developer.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, ، يجب عليك في الأساس تجاوز المساواة والرمز الخاص بك لكائن الاسم واستخدامه ، ولكن إذا كنت ترغب في استخدام معايير البحث المخصصة ، أعتقد أنه يتعين عليك تنفيذ طريقتك الخاصة وليس هناك دعم لغة Java

استخدم قاعدة بيانات الذاكرة مثل أباتشي ديربي أو HSQLDB. استفد من JDBC أو JPA أو السبات ، والتي يمكن أن تفعل جميعًا ما تريد.

ملف تعريف الرمز الخاص بك. ثم تحسين.

الطريقة الأسرع التي يمكنني التفكير فيها ، هي إنشاء بنية بيانات تعكس قيم خاصية الكائنات هذه والاحتفاظ بالفهرس الداخلي لكل قيمة.

عند البحث عن قيمة ، ستعيد بنية البيانات الداخلية هذه الفهرس باستخدام البحث الثنائي.

الشرط الوحيد هو أن كائنك يجب أن يسجل وتحديث هذا الهيكل.

شيء مثل الرمز الخيالي التالي مثل الكود:

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

عندما تبحث عن سمة معينة ، فإنك تأخذ المصفوفة المقابلة ، على سبيل المثال ، إذا كنت ستنظر في الاسم الأخير "Reyes" سوف تأخذ "اسم" LastName "

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

وسوف يؤدي البحث الثنائي على "Reyes" الذي سيعيد العنصر في الموضع 2 ، والذي بدوره سيعود الفهرس = 1 Whih هو موضع "Oscar" في الصفيف الأصلي.

هذا يجب أن يبقي الأشياء تحت o (log n)

انظر إلى فئة الموازي ، فهو يفي بمتطلباتك ، ولكن عليك أن تتعلم القليل من مفاهيم البرمجة الوظيفية لاستخدامها بكفاءة.

لا يأتي الفصل مع JDK 6 ، ولكن قد يأتي مع JDK 7 (قيد المناقشة). وفي الوقت نفسه ، يمكنك استخدامه كمكتبة - قم بتنزيل حزمة JSR166Y من:http://gee.cs.oswego.edu/dl/concurrency-interest/

انظر هذا البرنامج التعليمي لتفسير مفصل:http://www.ibm.com/developerworks/java/library/j-jtp03048.html

قد يبدو الأمر معقدًا وهو (إذا كنت تقوم فقط بحفر في خوارزميات متعددة الخيوط عالية الأداء). يوجد مشروع رائع يحاول لف واجهة برمجة تطبيقات سهلة الاستخدام حول مجموعة متوازية ، لذلك قد ترغب في إلقاء نظرة عليه أيضًا: http://gpars.codehaus.org/ , http://gpars.codehaus.org/parallelizer

أضافت Java 8 تعبيرات Lambda و API Stream ، لذلك أصبح الدعم مدمجًا الآن.

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