문제

Not quite sure how to word this question. I am wondering if there is a method to check certain parts of a custom java class to see if it matches a certain criteria. Such as this

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

And then when an array of instances of that class are created say,

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

Is it possible to do a search over the instances of the class for person with

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

I am not really looking for a solution that is if(surname.equals("bob")) then else,etc

But more a in-built java class that allows for rapid searching over the array. the speed of this is very important.

도움이 되었습니까?

해결책

There isn't built in support, but Apache Collections and Google Collections both provide Predicate support over collections.

You may find this question and its answers helpful. Same with this developer.com article.

e.g. Using Google Collections:

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

다른 팁

Searching through an array and "speed is very important" don't really go together. Unless if your array will be very small then searching through an array will never be quick. This is the equivalent of a full table scan in a database, performance no matter how you go about it will be poor. The key to finding things quickly is to use an indexed structure. You can still have an array if you absolutely need it but the searching should be done using another data structure. Check out a Hash or Tree based collection since they organize data in a way that make it very fast to retrieve. TreeSet, TreeMap, HashSet, HashMap, etc. Hashes index data on a hashed key, Trees are similar but also store their data in a sorted order.

If you need to search based on the object equality over array check apache common ArrayUtils, You basically have to override your equals and hascode for name object and use it, but if you want to use custom search criteria, I guess you have to implement your own way and there is no built in java language support

Use an in memory database like Apache Derby or hsqldb. Take advantage of JDBC, JPA, or Hibernate, which can all do what you want.

Profile your code. Then optimize.

The faster way I can think of, is to create a data structure which mirrors this objects property values and hold the internal index for each value has.

When a value is searched, this internal data structure will return the index using binary search.

The only requirement is your object must register and update this structure.

Something like the following imaginary UML/Python like 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

I hope this is understandable.

The point is, if you really what to have this really fast, you have to hold the indexes by property

  1. An array for the data
  2. An array for each property, which in turn would have the index of data

For instance if you have the following array:

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

They would have the positions:

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

And you'll have two ( in this case ) separate arrays which after being sorted would be:

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

and

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

When you search for a given attribute, you take the corresponding array, for instance, if you wan to search the last name "Reyes" you'll take "lastName" array

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

And will perform binarySearch on it for "Reyes" which will return the element at position 2, which in turn will return the index = 1 whih is the position "Oscar" has in the original array.

This should keep things under O(log n)

다른 버그 중에는 TForm.Stylebook 속성이 자동으로 할당되지 않는 경우가 있습니다.할당되었는지 확인하는 경우 위의 단계가 작동합니다.

빠른 단계 :

  1. 형식을 만듭니다.
  2. 양식에 스타일 책을 삭제하고 form.stylebook= stylebook1
  3. 스타일을 수정하려는 컨트롤을 마우스 오른쪽 단추로 클릭하고 사용자 정의 스타일 편집을 클릭합니다.
  4. 객체 검사기로 이동하여 PANEL의 배경색을 변경하기 위해 FILL 속성을 수정하여 패널의 배경색을 변경합니다.
  5. 적용 및 닫습니다.(창 초점 버그로 인해 2 개, 3 ~ 4 회 클릭)

    여기에 이미지 설명

    참고 :이 해결 방법은 Delphi XE4에서 유용하지 않으며 모바일 응용 프로그램 FMX에서 "사용자 정의 스타일 설정"기능이 제거되었습니다.

Java 8 added lambda expressions and the stream API, so support is built-in now.

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

There are lots of options available here. You can get the first name to match by switching .findAny() to .findFirst() or run the search in parallel by inserting .parallel() after .stream(applicants), for example.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top