不太确定如何说出这个问题。 我想知道是否有一种方法来检查自定义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类允许快速搜索数组。 速度非常重要。
答案 0 :(得分:14)
没有内置支持,但Apache Collections和Google Collections都提供Predicate对集合的支持。
您可能会发现this question及其答案很有帮助。与此developer.com文章相同。
e.g。使用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));
答案 1 :(得分:1)
通过数组搜索和“速度非常重要”并不是真的在一起。除非您的阵列非常小,否则搜索数组将永远不会很快。这相当于数据库中的全表扫描,性能无论你如何去做都会很差。快速查找内容的关键是使用索引结构。如果你绝对需要它,你仍然可以有一个数组,但搜索应该使用另一种数据结构。检查基于哈希或树的集合,因为它们以一种使检索速度非常快的方式组织数据。 TreeSet,TreeMap,HashSet,HashMap等。散列键上的哈希索引数据,树类似,但也按排序顺序存储它们的数据。
答案 2 :(得分:0)
如果你需要基于数组检查apache common ArrayUtils
上的对象相等进行搜索,你基本上必须覆盖你的equals和hascode for name对象并使用它,但是如果你想使用自定义搜索条件,我猜你必须以自己的方式实现,并且没有内置的java语言支持
答案 3 :(得分:0)
使用内存数据库,例如Apache Derby或hsqldb。利用JDBC,JPA或Hibernate,它们都可以满足您的需求。
描述您的代码。然后优化。
答案 4 :(得分:0)
我能想到的更快的方法是创建一个数据结构,它反映这个对象的属性值并保存每个值的内部索引。
搜索值时,此内部数据结构将使用二进制搜索返回索引。
唯一的要求是您的对象必须注册并更新此结构。
类似于以下虚构的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
糟糕
我希望这是可以理解的。
关键是,如果你真的要快得多,你必须按属性
保存索引例如,如果您有以下数组:
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,这是“Oscar”在原始数组中的位置。
这应该保持在O(log n)
之下答案 5 :(得分:0)
查看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项目试图围绕Parallel Array包装一个更加用户友好的API,所以你可能也想看看它:http://gpars.codehaus.org/,http://gpars.codehaus.org/Parallelizer
答案 6 :(得分:0)
Java 8添加了lambda表达式和流API,因此现在内置了支持。
.findAny()
这里有很多选择。您可以通过将.findFirst()
切换为.parallel()
来获得要匹配的名字,或者通过在.stream(applicants)
之后插入import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Kalkulator {
public static void main(final String... args) {
System.out.println("enter any number of doubles, whitespace delimited. enter a non-double token to quit");
final List<Double> doubles = new ArrayList<>();
try (final Scanner dane = new Scanner(System.in)) {
while (dane.hasNextDouble()) {
final double input = dane.nextDouble();
doubles.add(input);
System.out.println(String.format("Read [%f]", input));
}
}
System.out.println(String.format("finished reading user input. %d doubles read.", doubles.size()));
System.out.println(String.format("Largest input: %f", doubles.stream().reduce(Math::max).orElse(0D)));
System.out.println(String.format("Smallest input: %f", doubles.stream().mapToDouble(d -> d).min().orElse(0D)));
}
}
来并行运行搜索。