Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从流中获取中间结果,以便稍后在流中使用_Java_Algorithm_Java Stream_Unique - Fatal编程技术网

Java 从流中获取中间结果,以便稍后在流中使用

Java 从流中获取中间结果,以便稍后在流中使用,java,algorithm,java-stream,unique,Java,Algorithm,Java Stream,Unique,我试图编写一些函数式编程代码(使用Java 8中的lambdas和streams)来测试字符串中是否有唯一字符(如果有,则返回true,如果没有,则返回false)。使用vanilla Java实现这一点的常用方法是使用类似集合的数据结构,即: public static boolean oldSchoolMethod(String str) { Set<String> set = new HashSet<>(); for(int i=0; i<s

我试图编写一些函数式编程代码(使用Java 8中的lambdas和streams)来测试字符串中是否有唯一字符(如果有,则返回
true
,如果没有,则返回
false
)。使用vanilla Java实现这一点的常用方法是使用类似集合的数据结构,即:

public static boolean oldSchoolMethod(String str) {
    Set<String> set = new HashSet<>();

    for(int i=0; i<str.length(); i++) {
        if(!set.add(str.charAt(i) + "")) return false;
    }
    return true;
}
我想解决这个问题的另一种方法是,只使用
distinct()
将结果收集到一个新字符串中,如果它与原始字符串的长度相同,那么你就知道它是唯一的,否则如果长度不同,一些字符会因不清晰而被过滤掉,因此,在比较长度时,您知道它不是唯一的。我在这里看到的唯一问题是,您必须遍历字符串的所有长度N个字符,其中“老派”方法最佳情况场景可以在几乎恒定的时间O(1)内完成,因为它正在中断循环,并在找到1个重复字符后立即返回:

public static boolean java8StreamMethod(String str) {
    String result = Arrays.stream(str.split(""))
            .distinct()
            .collect(Collectors.joining());

    return result.length() == str.length();
}

此代码可能适用于您:

public class Test {

    public static void main(String[] args) {

        String myInputString = "hellowrd";

        HashSet<String> set = new HashSet<>();
        Optional<String> duplicateChar =Arrays.stream(myInputString.split("")).
                filter(num-> !set.add(num)).findFirst();
        if(duplicateChar.isPresent()){
            System.out.println("Not unique");
        }else{
            System.out.println("Unique");
        }

    }
}
公共类测试{
公共静态void main(字符串[]args){
字符串myInputString=“hellowrd”;
HashSet=newhashset();
可选的duplicateChar=Arrays.stream(myInputString.split(“”))。
过滤器(num->!set.add(num)).findFirst();
if(duplicateChar.isPresent()){
System.out.println(“非唯一”);
}否则{
System.out.println(“唯一”);
}
}
}

这里使用
findFirst()
我可以找到第一个重复的元素。这样我们就不需要继续迭代其余的字符了。

直接映射到布尔值怎么样

Arrays.stream(myInputString.split(""))
   .map(set::add)
   .<...>
Arrays.stream(myInputString.split(“”))
.map(集合::添加)
.
我想这将解决您的具体问题,但这不是一个很好的解决方案,因为流链中的闭包不应该有副作用(这正是函数编程的要点…)


有时,对于某些问题,经典for循环仍然是更好的选择;-)

您的解决方案都在执行不必要的字符串操作

例如,不使用
集合
,您可以使用
集合

公共静态布尔betterOldSchoolMethod(字符串str){
Set=newhashset();

对于(int i=0;i你的问题是什么?这回答了你的问题吗?你的“其他方式”与第一次尝试没有什么不同(除了它有效),它也将在流处理继续之前循环遍历所有字符,您将有机会调查一组布尔值,以查看一个或多个布尔值是否为假。除非您在这里处理数十万个字符,否则您将进行微优化。编写有效、可读且易于维护的代码。这是非常重要的顺便提一下,这是一个典型的X/Y问题。你想解决一个问题,并且自己选择了一个解决方案,然后问一个关于该解决方案的问题(X)。最好是问一个关于该问题的问题(Y).ChiefGokhlayeh似乎很好的回答解决了这个问题,而不是你的解决方案。这使得答案有点错误,因为它没有回答你的问题……但很可能它确实回答了,你只是没有问对问题。@Gimby,正如我链接的建议副本中所指出的,设置版本(
oldSchoolMethod
)实际上是最好的解决方案。这个问题不能很好地转化为流(对于许多不能独立处理元素的算法来说也是如此)。所有流版本都要求有状态谓词短路,这会破坏流的许多好处。Okay更新了答案。此外,使用
anyMatch
将消除对可选和
isPresent()的需要
检查。但是,这仍然不能克服循环-最多它可以是等价的。我知道最短的流版本是Holgers
return list.stream().allMatch(新的HashSet()::add)
,但它仍然有同样的问题(有状态谓词)-请参阅Stuart Marks的警告性评论。啊!我认为findFirst()以这种方式实现是我一直在寻找的是的-如果不借助有状态谓词,就无法用流解决这个问题-最好还是坚持循环。然而,映射到
布尔值
很少有用。
anyMatch
allMatch
通常是一种方法。当您使用此方法向集合中添加副本?如果在映射后添加filter.findAny或任何匹配项,则可以中断。如果是OP,则选择哪一个?@HadiJ取决于上下文。如果性能关键,
evenberteroldschoolmethod
,否则,
newMethod
在可读性最重要的时候(如“chars distinct count”非常精确地描述了它在做什么
Arrays.stream(myInputString.split(""))
   .map(set::add)
   .<...>