Java检查数组元素重复是否存在而不使用循环?

Java检查数组元素重复是否存在而不使用循环?,java,loops,collections,Java,Loops,Collections,我制作了一个成对单词检测器,它给我的输出是true或false 如果字符串数组中的值包含相同的字符串字母(重复),则返回true 我使用了下面使用嵌套循环的代码 现在,我想在不使用任何循环的情况下实现相同的概念? 我如何做到这一点,需要什么样的示例或什么类型的java集合框架? 多谢各位 主要内容: 分: 公共类Pairfinder { 公共静态布尔测试(字符串[]值) {

我制作了一个成对单词检测器,它给我的输出是
true
false

如果字符串数组中的值包含相同的字符串字母(重复),则返回
true

我使用了下面使用嵌套循环的代码
现在,我想在不使用任何循环的情况下实现相同的概念?
我如何做到这一点,需要什么样的示例或什么类型的
java集合框架?
多谢各位

主要内容:

分:

公共类Pairfinder
{                                       
公共静态布尔测试(字符串[]值)
{                                     
对于(int i=0;i
是的,您可以在时间复杂度O(n)
想法是
将所有项目放入
哈希集中

如果
数组
包含重复值
哈希集的长度
将不等于
数组的长度

因为
HashSet
add函数会将指定的元素添加到此集合中(如果该元素尚未存在)

public static boolean test(String[] value) {
    Set<String> hashSet = new HashSet<>(Arrays.asList(value));
    return (value.length != hashSet.size());
}
公共静态布尔测试(字符串[]值){
Set hashSet=新的hashSet(Arrays.asList(value));
返回值(value.length!=hashSet.size());
}

您可以使用带有一行程序的Java流:

public static boolean test(String[] value) {
    return Arrays.stream(value).anyMatch(v -> Collections.frequency(Arrays.asList(value), v) > 1);
}
但这可能不是最有效的解决方案,因为它的时间复杂度为O(n²)

或者,您也可以使用
distinct()

由于
frequency()
计数,此版本的时间复杂度也为O(n²)。更好的解决办法是:

public static String[] getDuplicates(String[] value) {
    return Arrays.stream(value)
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet().stream()
            .filter(e -> e.getValue() > 1)
            .map(Map.Entry::getKey)
            .toArray(String[]::new);
}

下面是一个简单的例子

public static void main(String[] args) {
    String[] box = {"Monkey", "Lion", "Elephant", "Zebra", "Tiger", "Hippo"};
    String[] box2 = {"Shop", "Biscuit", "Cake", "Cake"};
    String[] box3 = {"Entrance", "Gate", "Price", "Door", "Gate"};
    String[] box4 = {"Female", "Male"};
    System.out.println(checkIt(box));        //false                                
    System.out.println(checkIt(box2));       //true                                 
    System.out.println(checkIt(box3));       //true  
    System.out.println(checkIt(box4));           //false   

}

public static boolean checkIt(String[] text) {
    return !Arrays.stream(text).allMatch(new HashSet<>()::add);
}
publicstaticvoidmain(字符串[]args){
字符串[]框={“猴子”、“狮子”、“大象”、“斑马”、“老虎”、“河马”};
字符串[]box2={“商店”、“饼干”、“蛋糕”、“蛋糕”};
字符串[]box3={“入口”、“门”、“价格”、“门”、“门”};
字符串[]box4={“女性”,“男性”};
System.out.println(checkIt(box));//false
System.out.println(checkIt(box2));//true
System.out.println(checkIt(box3));//true
System.out.println(checkIt(box4));//false
}
公共静态布尔checkIt(字符串[]文本){
return!Arrays.stream(text).allMatch(新HashSet()::add);
}

没有循环?你的意思是用lambda表达式吗?您必须以某种方式在数组上迭代以查找重复项。您可以尝试将所有项插入一个集合(不允许重复项)-如果集合小于数组,则您有重复项。^这可以工作,但集合将在幕后使用循环。您可以使用流。使用Arrays.stream并将它们收集到按值本身分组的映射中。然后对计数大于1的过滤器进行下游过滤。如果结果至少有1个条目,则存在重复项。为了更好地隐藏循环,为什么不
Set Set=new HashSet(Arrays.asList(value))?这里的
独特的
解决方案是最好的。集合(其他答案)是清晰的,但
不同的
集合与集合一样可读。
anyMatch
版本很聪明,但它让我不得不思考;-)
anyMatch
解决方案非常糟糕,因为它会在整个数组中搜索每个数组元素,也称为“二次时间复杂度”。
distinct()
变量不错,但看起来仍然像是过度使用流API,一个好的旧
返回新的HashSet(Arrays.asList(value)).size()==value.length也可以。再次对每个元素执行
getDuplicates
变量
frequency
,将再次导致二次时间复杂度。您可以使用
.collect(groupingBy(Function.identity(),counting()).entrySet().stream().filter(e->e.getValue()>1).map(e->e.getKey).toArray(字符串[]::new)谢谢@Holger我已经注意到了
frequency()
的时间复杂性,但我在回答中没有明确提到。我更新了它并添加了另一个查找重复项的示例。@Holger哦,刚刚复制了它,但忘记删除该部分:D再次感谢。我必须考虑的另一个聪明的解决方案:-)我仍然喜欢@SamuelPhilipp的
独特的
,但很高兴看到这么多不同的方法都能奏效!
public static boolean test(String[] value) {
    return Arrays.stream(value).distinct().count() < value.length;
}
public static String[] getDuplicates(String[] value) {
    return Arrays.stream(value)
            .filter(v -> Collections.frequency(Arrays.asList(value), v) > 1)
            .distinct()
            .toArray(String[]::new);
}
public static String[] getDuplicates(String[] value) {
    return Arrays.stream(value)
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet().stream()
            .filter(e -> e.getValue() > 1)
            .map(Map.Entry::getKey)
            .toArray(String[]::new);
}
public static void main(String[] args) {
    String[] box = {"Monkey", "Lion", "Elephant", "Zebra", "Tiger", "Hippo"};
    String[] box2 = {"Shop", "Biscuit", "Cake", "Cake"};
    String[] box3 = {"Entrance", "Gate", "Price", "Door", "Gate"};
    String[] box4 = {"Female", "Male"};
    System.out.println(checkIt(box));        //false                                
    System.out.println(checkIt(box2));       //true                                 
    System.out.println(checkIt(box3));       //true  
    System.out.println(checkIt(box4));           //false   

}

public static boolean checkIt(String[] text) {
    return !Arrays.stream(text).allMatch(new HashSet<>()::add);
}