Java 如何在函数中的子字符串和比较器中的两个值中实现二进制搜索?

Java 如何在函数中的子字符串和比较器中的两个值中实现二进制搜索?,java,binary-search,Java,Binary Search,我对在子字符串中实现二进制搜索有一个问题。在my City对象中,有一个定义为字符串的cityName变量。我想输入任何像“Sha”这样的子字符串,它会显示“Sha”的结果。除此之外,还有一个权重变量用于对城市名称进行排序。例如,较大的权重值位于顶部,排序过程基于降序 我该怎么做?如何将其添加到比较器区域 这是我的城市目标 public class City implements Serializable{ private Integer cityWeight; private

我对在子字符串中实现二进制搜索有一个问题。在my City对象中,有一个定义为字符串的cityName变量。我想输入任何像“Sha”这样的子字符串,它会显示“Sha”的结果。除此之外,还有一个权重变量用于对城市名称进行排序。例如,较大的权重值位于顶部,排序过程基于降序

我该怎么做?如何将其添加到
比较器
区域

这是我的城市目标

public class City implements Serializable{
    private Integer cityWeight;
    private String cityName;
}
下面是我的代码片段,如下所示

//不实现二进制搜索

public static Integer[] searchByCharacters(List<City> list, String sub) {
        List<Integer> result = new ArrayList<>();
        Collections.sort(list);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getCityName().contains(sub))
                result.add(i);
        }
        return result.stream().toArray(Integer[]::new);
}
public static Integer[]searchByCharacters(列表,字符串子列表){
列表结果=新建ArrayList();
集合。排序(列表);
对于(int i=0;i
我想在代码段上方实现二进制搜索,但它不起作用

public static Integer[] searchBySubStringCharacter(List<City> list, String sub) {
        List<Integer> result = new ArrayList<>();

        Comparator<City> comparator = new Comparator<City>() {
            public int compare(City node1, City node2) {
                boolean node1Contains = node1.getCityName().contains(sub);
                boolean node2Contains = node2.getCityName().contains(sub);
                if (node1Contains && !node2Contains) {
                    return 1;
                } else if (!node1Contains && node2Contains ) {
                    return -1;
                } else {
                    return 0;
                }
            }
        };

        Collections.sort(list, comparator);
        for (int i = 0; i < list.size(); i++) {
            int index = Collections.binarySearch(list, new City(sub), comparator);
            if (index >= 0)
                result.add(i);
        }

        return result.stream().toArray(Integer[]::new);
    }
public static Integer[]searchBySubStringCharacter(列表,字符串子){
列表结果=新建ArrayList();
比较器比较器=新比较器(){
公共整数比较(城市节点1、城市节点2){
布尔值node1Contains=node1.getCityName().contains(sub);
布尔值node2Contains=node2.getCityName().contains(sub);
if(node1Contains&!node2Contains){
返回1;
}如果(!node1Contains&&node2Contains){
返回-1;
}否则{
返回0;
}
}
};
集合。排序(列表、比较);
对于(int i=0;i=0)
结果.添加(i);
}
返回result.stream().toArray(整数[]:新);
}

此代码显示所有城市列表和二进制搜索的结果。如何从结果中提取所有城市列表?

binarySearch
接受要搜索的键,以便键入列表中对象的类别

public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
另外,如果您使用的是java8+,则可以将lambda用于
比较器

Comparator<City> comparator = (node1, node2) -> {
     boolean node1Contains = node1.getCityName().contains(sub);
     boolean node2Contains = node2.getCityName().contains(sub);
     if (node1Contains && !node2Contains) {
        return 1;
     } else if (!node1Contains && node2Contains ) {
        return -1;
     } else {
        return 0;
     }
};

您可以添加“从字符串创建城市对象”并进行如下搜索:

  public static Integer[] searchBySubStringCharacter(List<City> list, String sub) {
        List<Integer> result = new ArrayList<>();

        Comparator<City> comparator = new Comparator<City>() {
            public int compare(City node1, City node2) {
                boolean node1Contains = node1.getCityName().contains(sub);
                boolean node2Contains = node2.getCityName().contains(sub);
                if (node1Contains && !node2Contains) {
                    return 1;
                } else if (!node1Contains && node2Contains) {
                    return -1;
                } else {
                    return 0;
                }
            }
        };

        Collections.sort(list, comparator);
        for (int i = 0; i < list.size(); i++) {
            int index = Collections.binarySearch(list, new City(sub), comparator);
            if (index >= 0)
                result.add(i);
        }

        return result.stream().toArray(Integer[]::new);
    }
public static Integer[]searchBySubStringCharacter(列表,字符串子){
列表结果=新建ArrayList();
比较器比较器=新比较器(){
公共整数比较(城市节点1、城市节点2){
布尔值node1Contains=node1.getCityName().contains(sub);
布尔值node2Contains=node2.getCityName().contains(sub);
if(node1Contains&!node2Contains){
返回1;
}如果(!node1Contains&&node2Contains){
返回-1;
}否则{
返回0;
}
}
};
集合。排序(列表、比较);
对于(int i=0;i=0)
结果.添加(i);
}
返回result.stream().toArray(整数[]:新);
}
,或避免每次迭代都创建城市对象,并接受城市作为参数

public static Integer[] searchBySubStringCharacter(List<City> list, City sub) {
        List<Integer> result = new ArrayList<>();

        Comparator<City> comparator = new Comparator<City>() {
            public int compare(City node1, City node2) {
                boolean node1Contains = node1.getCityName().contains(sub.getCityName());
                boolean node2Contains = node2.getCityName().contains(sub.getCityName());
                if (node1Contains && !node2Contains) {
                    return 1;
                } else if (!node1Contains && node2Contains) {
                    return -1;
                } else {
                    return 0;
                }
            }
        };

        Collections.sort(list, comparator);
        for (int i = 0; i < list.size(); i++) {
            int index = Collections.binarySearch(list, sub, comparator);
            if (index >= 0)
                result.add(i);
        }

        return result.stream().toArray(Integer[]::new);
    }
public static Integer[]searchBySubStringCharacter(列表,城市子列表){
列表结果=新建ArrayList();
比较器比较器=新比较器(){
公共整数比较(城市节点1、城市节点2){
布尔值node1Contains=node1.getCityName().contains(sub.getCityName());
布尔值node2Contains=node2.getCityName().contains(sub.getCityName());
if(node1Contains&!node2Contains){
返回1;
}如果(!node1Contains&&node2Contains){
返回-1;
}否则{
返回0;
}
}
};
集合。排序(列表、比较);
对于(int i=0;i=0)
结果.添加(i);
}
返回result.stream().toArray(整数[]:新);
}

现有答案可能会解决您的编译问题,但。。。这种方法的目的是什么?看起来您将对列表进行排序,然后找到第一个匹配项的索引,然后用该值填充列表大小的数组,然后返回该数组。我猜这不是你的目标。@vsfDawg我编辑了我的文章。我将尝试你的代码,但有一个问题。结果显示所有城市,然后显示searchBySubStringCharacter的结果。结果完全取决于您的
比较器
逻辑。for循环中存在问题。我已经完成了我的项目并上载了我的github存储库。搜索零件时出现问题。当我写“莫斯科”时,它显示2个结果,但不显示1个结果。如果你不介意的话,你能检查一下我的项目吗。第一个(public static Integer[]searchBySubStringCharacter(List List,String sub))获取完整的对象列表和类似(“Sha”)的搜索结果。for循环部分存在问题。我正在等待您的响应。顺便问一下,在这种情况下,为什么需要使用
BinarySearch
,因为线性搜索将很好
O(n)
而不是排序的复杂性,然后应用搜索
  public static Integer[] searchBySubStringCharacter(List<City> list, String sub) {
        List<Integer> result = new ArrayList<>();

        Comparator<City> comparator = new Comparator<City>() {
            public int compare(City node1, City node2) {
                boolean node1Contains = node1.getCityName().contains(sub);
                boolean node2Contains = node2.getCityName().contains(sub);
                if (node1Contains && !node2Contains) {
                    return 1;
                } else if (!node1Contains && node2Contains) {
                    return -1;
                } else {
                    return 0;
                }
            }
        };

        Collections.sort(list, comparator);
        for (int i = 0; i < list.size(); i++) {
            int index = Collections.binarySearch(list, new City(sub), comparator);
            if (index >= 0)
                result.add(i);
        }

        return result.stream().toArray(Integer[]::new);
    }
public static Integer[] searchBySubStringCharacter(List<City> list, City sub) {
        List<Integer> result = new ArrayList<>();

        Comparator<City> comparator = new Comparator<City>() {
            public int compare(City node1, City node2) {
                boolean node1Contains = node1.getCityName().contains(sub.getCityName());
                boolean node2Contains = node2.getCityName().contains(sub.getCityName());
                if (node1Contains && !node2Contains) {
                    return 1;
                } else if (!node1Contains && node2Contains) {
                    return -1;
                } else {
                    return 0;
                }
            }
        };

        Collections.sort(list, comparator);
        for (int i = 0; i < list.size(); i++) {
            int index = Collections.binarySearch(list, sub, comparator);
            if (index >= 0)
                result.add(i);
        }

        return result.stream().toArray(Integer[]::new);
    }