java替代使用嵌套for循环
Posted
技术标签:
【中文标题】java替代使用嵌套for循环【英文标题】:java alternative to using nested for loops 【发布时间】:2022-01-14 11:33:08 【问题描述】:我有一个包含两个字段的策略对象:policyNumber 和 policyStatus。我将有一份保单列表,我需要查看是否有任何保单具有我提供的状态之一。如果有,我将布尔值设置为是。如果没有,我将其设置为否。
通常我会像这样使用嵌套的 for 循环:
Boolean hasStatus = false;
List<Policy> policies = new List<Policy>();
String[] statuses = String[]'A1','A3','B6','T1','T6';
for (Policy policy : policies)
for (int i=0; i<statuses.length; i++)
if (policy.policyStatus == statuses[i]
hasStatus = true;
break;
return hasStatus;
现在我在涉及地图、集合和集合以及算法的领域非常周到。我想知道是否有一些事情是我应该做的,而不是使用嵌套的 for 循环和 if 块。如果有,请您给我一些指导吗?还是我真的应该这样做?
【问题讨论】:
请注意'A1'
(etc) 不是String
s:您需要使用"A1"
,并带有双引号。此外,您几乎肯定不想使用==
,而应该使用equals
。
还要注意break跳出当前循环。见***.com/questions/886955/…
【参考方案1】:
在深入研究之前,我想解决几个问题。
List
是一个接口,所以不能实例化这种类型的对象。但是,您可以使用 ArrayList
来实例化它。您不必直接使用policy.policyStatus
访问成员,您应该考虑使用getter 来确保封装,所以policy.getStatus()
。
使用过滤器和地图!正如安迪雄辩地所说,这是一个非常干净和优雅的解决方案。希望这也有帮助!
简短补充:我认为 java 流有时有点过于复杂,但它们非常有用。如果您使用.stream()
流式传输集合,这将使Java 逐个查看集合的每个成员。然后你可以使用一堆很酷的方法。
...stream().map()
只是将一个函数一个一个地应用于单个对象。这个功能可以是任何东西! java中的function
接口有一个方法R apply(T t);
——所以它接受一个输入,并产生一个输出。如您所见,R 类型的输出可能与 T 类型的输入不同。如果您不想返回任何内容,可以直接在集合上使用集合 forEach
方法。此方法采用consumer
,类似于function
,但它不返回任何内容。你也可以做...stream().filter()
,它接受predicate
,基本上是一个评估为真或假的问题。所有这些只是为了代码的简单性,java中的函数式编程实际上在野外非常有用:D
【讨论】:
感谢您指出语法错误!我的坏 :D 但是 a == b 总是错误的,在你的 ide 中尝试一下。字符串是对象,而不是文字。 哇,我不知道。我一直认为==
会返回 false(我可能从 uni 的早期误解了这一点)并且总是使用 .equals,感谢您指出我的错误。我在我的ide中重新运行了它!我会相应地改变我的答案。
我的立场是正确的。我删除了部分答案,感谢您指出:D
尽管如此,您是正确的,(几乎)总是equals
是比较字符串的正确方法【参考方案2】:
您可以将Policy
类实现为policyStatus
和policyNumber
的映射(在这种情况下policyStatus
是键policyNumber
是Map
的值)并像这样执行您的检查:
Boolean hasStatus = false;
Map<String, Integer> policyMap = getPolicyMap();
String[] statuses = String[]"A1", "A3", "B6", "T1", "T6";
for (String status : statuses)
if(policyMap.get(status) != null)
hasStatus = true;
break;
return hasStatus;
或者如果你不能这样做并且你的statuses
的长度是恒定的或者长度上的上限很小,你不应该担心在你的项目中有一个带有嵌套循环的子例程。因为这是不可能的。你所做的是在n
的数组上搜索m
元素,没有任何先验条件或知识,你需要O(nm)
比较,所以你需要嵌套循环。但正如我所说,您可以使用 Map
数据结构重构您的代码并使用单循环。
【讨论】:
【参考方案3】:构造一个包含状态的Set<String>
:
Set<String> statusSet = new HashSet<>(statuses);
然后使用流迭代policies
:
return policies.stream().anyMatch(p -> statusSet.contains(p.policyStatus));
【讨论】:
如果我们的数组有n
长度并且我们的列表有m
,这个子例程仍然执行它与O(nm)
比较的工作,所以从技术上讲它是一个嵌套循环。我说的对吗?
@Mahdi 我相信不是,HashSet
使用的哈希算法性能优于 O(n)(最终是恒定时间)
@MahdiYusefi 在HashSet
中的查找是 O(1)。以上是关于java替代使用嵌套for循环的主要内容,如果未能解决你的问题,请参考以下文章
小白学Java for循环3分钟学会Java的for循环,让看懂for循环嵌套再不是难事