下面是我的代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class MyComp implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}
public class CollectionsAlgo2 {
public static void main(String[] args) {
// Create an ArrayList
ArrayList<String> al = new ArrayList<>();
// Add elements to the array list.
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
al.add(1, "A2");
System.out.println("al: "+al);
Collections.sort(al);
System.out.println("al after sorting: "+al);
int pos = Collections.binarySearch(al, "B", new MyComp());
System.out.println("pos: "+pos);
}
}
我的问题是在Collections.binarySearch(List<?extends T> list,T key,Comparator<?super T> c),因为我们已经按升序传递了列表?
这个比较器参考如何帮助进行二分搜索?
3条答案
按热度按时间xpcnnkqh1#
基本上,二分查找算法需要知道如何比较元素。当它检查一个平分点时,它需要知道你要搜索的元素是在左边还是右边。这需要一个比较。
Collections
有两个binarySearch
方法,一个有比较器,一个没有。如果你的元素是Comparable
,那么你不需要传递一个比较器。你可以只传递列表和搜索键:如果它们不是
Comparable
,那么你需要告诉binarySearch
如何通过传递一个自定义的Comparator
来比较它们:在示例代码中,
String
是Comparable
,因此不需要MyComp
。41zrol4v2#
请记住,Java的数组类中有许多不同的方法可以使用二进制搜索。你可以找到一个here的列表。
一般来说,如果你在数组或列表中搜索一个原语、字节或类似的对象,你应该使用一个不包含任何比较器的方法。
但是,如果您有一个默认情况下不可比较的对象列表,该怎么办?例如,假设您定义了一个
Person
数据类型,它具有一些属性,如身高、年龄和名称。现在,假设您正在存储一个人员列表。如果你想在Person
对象的排序列表中找到某个Person
,默认情况下,Java不知道如何执行这种二分搜索。需要提醒的是,Java通过比较当前检查的键和目标键来确定在二进制搜索中移动的位置。但是,Java不知道检查一个
Person
对象是否大于、小于或等于另一个对象意味着什么。它是否应该使用高度来确定哪个更大?是否应该根据姓氏或其他变量进行比较?这就是比较器的用武之地。我需要告诉Java,当我请求比较两个
Person
对象时,这意味着什么。要编写比较器,您需要创建一个类。这可以是与对象在同一文件中的私有类,或者您甚至可以将其写入方法本身。比较器应采用两种方法:
compare
和equals
。您可以查看文档here。一旦你写了这个,你就传入了你刚刚创建的比较器,所以Java现在知道如何比较给定列表或数组中的对象。c0vxltue3#
有两组sort()和binarySearch()。它们必须匹配,因为binarySearch()必须接受一个按升序排序的列表。
方法需要T extends Comparable<?你正在使用Comparable的实现进行排序和搜索。不需要设置比较器。
Javadoc for binarySearch:
在进行此调用之前,列表必须根据其元素的自然顺序(如通过**sort(List)**方法)按升序排序。
所有方法都不需要T extends Comparable<?super T>。即使你已经实现了Comparable,你现在也可以选择作为一个不同的Comparator来排序和搜索。
Javadoc for binarySearch:
在进行此调用之前,必须根据指定的比较器(如通过**sort(List,Comparator)**方法)将列表按升序排序。