Java에서 네스트된 루프를 해제하려면 어떻게 해야 하나요?
네스트 루프 구조는 다음과 같습니다.
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
break; // Breaks out of the inner loop
}
}
}
어떻게 하면 양쪽 루프를 벗어날 수 있을까요?비슷한 질문들을 살펴봤지만 자바와 관련된 질문은 없습니다.대부분 goto를 사용했기 때문에 이 솔루션을 적용할 수 없었습니다.
내부 루프를 다른 방법으로 배치하고 싶지 않습니다.
루프를 돌려주고 싶지 않아끊어지면 루프 블록 실행이 종료됩니다.
다른 응답자처럼 루프를 다른 방법으로 배치하는 것이 좋습니다. 그러면 반복을 완전히 멈출 수 있습니다.이 답변은 질문의 요건을 충족하는 방법을 보여줍니다.
하시면 됩니다.break외부 루프에 대한 라벨이 부착되어 있습니다.예를 들어 다음과 같습니다.
public class Test {
public static void main(String[] args) {
outerloop:
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
break outerloop;
}
System.out.println(i + " " + j);
}
}
System.out.println("Done");
}
}
다음의 출력이 있습니다.
0 0
0 1
0 2
0 3
0 4
1 0
1 1
1 2
1 3
1 4
2 0
2 1
2 2
2 3
Breaking
Done
기술적으로 정답은 외부 루프에 라벨을 붙이는 것입니다.실제로 내부 루프 내의 임의의 포인트에서 종료하는 경우는, 코드를 메서드(필요한 경우는 스태틱한 메서드)로 외부화한 후 호출하는 것이 좋습니다.
그것은 가독성에 대한 보상을 받을 것이다.
코드는 다음과 같습니다.
private static String search(...)
{
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
return search;
}
}
}
return null;
}
승인된 답변의 예와 일치:
public class Test {
public static void main(String[] args) {
loop();
System.out.println("Done");
}
public static void loop() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
return;
}
System.out.println(i + " " + j);
}
}
}
}
루프 주위에 이름 있는 블록을 사용할 수 있습니다.
search: {
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
break search;
}
}
}
}
라벨은 절대 안 써요.들어가는 건 나쁜 습관인 것 같아요.제가 할 일은 다음과 같습니다.
boolean finished = false;
for (int i = 0; i < 5 && !finished; i++) {
for (int j = 0; j < 5; j++) {
if (i * j > 6) {
finished = true;
break;
}
}
}
라벨을 사용할 수 있습니다.
label1:
for (int i = 0;;) {
for (int g = 0;;) {
break label1;
}
}
기능 사용:
public void doSomething(List<Type> types, List<Type> types2){
for(Type t1 : types){
for (Type t : types2) {
if (some condition) {
// Do something and return...
return;
}
}
}
}
임시 변수를 사용할 수 있습니다.
boolean outerBreak = false;
for (Type type : types) {
if(outerBreak) break;
for (Type t : types2) {
if (some condition) {
// Do something and break...
outerBreak = true;
break; // Breaks out of the inner loop
}
}
}
기능에 따라 내부 루프를 종료하거나 복귀할 수도 있습니다.
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
return;
}
}
}
가 에 들지 break §goto "할 수 있으며, 추가 조건인 "for-in"을 할 수 있습니다.
int a, b;
bool abort = false;
for (a = 0; a < 10 && !abort; a++) {
for (b = 0; b < 10 && !abort; b++) {
if (condition) {
doSomeThing();
abort = true;
}
}
}
저도 비슷한 작업을 해야 하는데 확장 루프를 사용하지 않기로 했습니다.
int s = type.size();
for (int i = 0; i < s; i++) {
for (int j = 0; j < t.size(); j++) {
if (condition) {
// do stuff after which you want
// to completely break out of both loops
s = 0; // enables the _main_ loop to terminate
break;
}
}
}
루프 테스트에 명시적인 "종료"를 추가하는 것을 선호합니다.루프가 조기에 종료될 수 있다는 것을 일반 독자에게 분명히 알립니다.
boolean earlyExit = false;
for(int i = 0 ; i < 10 && !earlyExit; i++) {
for(int j = 0 ; i < 10 && !earlyExit; j++) { earlyExit = true; }
}
복수의 루프를 종료할 필요가 있는 경우는, 「break」키워드만을 사용하는 것은 적절하지 않습니다.스테이트먼트에 둘러싸인 루프의 수에 관계없이 즉시 루프를 종료할 수 있습니다.라벨과 함께 '브레이크'를 사용할 수 있습니다!여기서는 "abc"라는 라벨을 사용했습니다. Java의 어떤 함수에서도 다음과 같이 코드를 쓸 수 있습니다.
이 코드는 가장 바깥쪽 루프에서 나가는 방법을 보여 줍니다.
abc:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
for (int k = 0; k < 10; k++) {
if (k == 1){
break abc;
}
}
}
}
또한 break 문을 사용하여 네스트 루프 내의 임의의 루프를 종료할 수도 있습니다.
for (int i = 0; i < 10; i++) {
abc:for (int j = 0; j < 10; j++) {
for (int k = 0; k < 10; k++) {
if (k == 1){
break abc;
}
}
}
}
다음 코드는 가장 안쪽 루프를 종료하는 예를 보여 줍니다.다른 작업에서는 다음 코드를 실행한 후, 당신은 'k' 변수들의 루프 바깥쪽에 있고, 여전히 'j' 변수들과 'i' 변수들의 루프 안에 있다.
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
for (int k = 0; k < 10; k++) {
if (k == 1){
break;
}
}
}
}
Java 8 솔루션:
List<Type> types1 = ...
List<Type> types2 = ...
types1.stream()
.flatMap(type1 -> types2.stream().map(type2 -> new Type[]{type1, type2}))
.filter(types -> /**some condition**/)
.findFirst()
.ifPresent(types -> /**do something**/);
라벨이 붙은 브레이크 개념은 Java에서 네스트된 루프를 분리하기 위해 사용됩니다.라벨이 붙은 브레이크를 사용하면 임의의 위치에서 루프의 네스트를 해제할 수 있습니다.예 1:
loop1:
for(int i= 0; i<6; i++){
for(int j=0; j<5; j++){
if(i==3)
break loop1;
}
}
루프가 3개 있고 loop3을 종료한다고 가정합니다.예 2:
loop3:
for(int i= 0; i<6; i++){
loop2:
for(int k= 0; k<6; k++){
loop1:
for(int j=0; j<5; j++){
if(i==3)
break loop3;
}
}
}
일반적으로 이러한 경우, 문제의 반복된 'for' 오브젝트를 검색하거나 조작하는 등 보다 의미 있는 로직의 범위 내에 있기 때문에, 저는 통상, 기능적인 어프로치를 사용합니다.
public Object searching(Object[] types) { // Or manipulating
List<Object> typesReferences = new ArrayList<Object>();
List<Object> typesReferences2 = new ArrayList<Object>();
for (Object type : typesReferences) {
Object o = getByCriterion(typesReferences2, type);
if(o != null) return o;
}
return null;
}
private Object getByCriterion(List<Object> typesReferences2, Object criterion) {
for (Object typeReference : typesReferences2) {
if(typeReference.equals(criterion)) {
// here comes other complex or specific logic || typeReference.equals(new Object())
return typeReference;
}
}
return null;
}
주요 단점:
- 약 두 줄 더
- 컴퓨팅 사이클 소비량 증가, 즉 알고리즘 관점에서 볼 때 속도가 느려집니다.
- 더 많은 타이핑 작업
장점:
- 기능적 입도 때문에 우려의 분리에 대한 비율이 높다.
- 없는 검색/조절 논리의 재추적 및 제어의 더 높은 비율
- 방법은 길지 않기 때문에 더 콤팩트하고 이해하기 쉽다
- 높은 가독성 비율
그래서 그것은 단지 다른 접근법으로 사건을 처리하고 있을 뿐이다.
기본적으로 이 질문의 작성자에게 질문합니다.이 접근방식에 대해 어떻게 생각하십니까?
label: 및 flags를 사용하지 않고 모든 루프에서 분리할 수 있습니다.
그냥 까다로운 해결책이야.
여기서 condition1은 루프 K 및 J에서 브레이크하기 위해 사용되는 조건입니다.condition2는 루프 K, J 및 I에서 브레이크하기 위해 사용되는 조건입니다.
예를 들어 다음과 같습니다.
public class BreakTesting {
public static void main(String[] args) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
for (int k = 0; k < 9; k++) {
if (condition1) {
System.out.println("Breaking from Loop K and J");
k = 9;
j = 9;
}
if (condition2) {
System.out.println("Breaking from Loop K, J and I");
k = 9;
j = 9;
i = 9;
}
}
}
}
System.out.println("End of I , J , K");
}
}
라벨을 사용합니다.
INNER:for(int j = 0; j < numbers.length; j++) {
System.out.println("Even number: " + i + ", break from INNER label");
break INNER;
}
이 기사를 참조해 주세요.
최적의 간단한 방법..
outerloop:
for(int i=0; i<10; i++){
// here we can break Outer loop by
break outerloop;
innerloop:
for(int i=0; i<10; i++){
// here we can break innerloop by
break innerloop;
}
}
데모
public static void main(String[] args) {
outer:
while (true) {
while (true) {
break outer;
}
}
}
boolean broken = false; // declared outside of the loop for efficiency
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
broken = true;
break;
}
}
if (broken) {
break;
}
}
만약 어떤 기능 안에 있다면 그냥 돌려보내는 게 어때요?
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
return value;
}
}
}
코드 길이(퍼포먼스가 아닌)에 관해서는 다소 특이한 접근법입니다.
for(int i = 0; i++; i < j) {
if(wanna exit) {
i = i + j; // if more nested, also add the
// maximum value for the other loops
}
}
예를 들어 설명하지 않은 다른 하나의 솔루션(실제로는 Prod Code로 동작합니다).
try {
for (Type type : types) {
for (Type t : types2) {
if (some condition #1) {
// Do something and break the loop.
throw new BreakLoopException();
}
}
}
}
catch (BreakLoopException e) {
// Do something on look breaking.
}
입니다.BreakLoopException, no-stack-module no-stack-module, no-stack-module(no-stack-module), no-stack-module(no-stack-module)을 해야 합니다.
private static class BreakLoopException extends Exception {
@Override
public StackTraceElement[] getStackTrace() {
return new StackTraceElement[0];
}
}
to it it it it it it it it it it 。label하려면 ,의 예를 생각해 라벨을 사용합니다이치노
public class Breaking{
public static void main(String[] args) {
outerscope:
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
if (condition) {
break outerscope;
}
}
}
}
}
또 다른 접근법은 브레이킹 변수/플래그를 사용하여 필요한 브레이킹을 추적하는 것입니다.다음 예를 들어 보겠습니다.
public class Breaking{
public static void main(String[] args) {
boolean isBreaking = false;
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
if (condition) {
isBreaking = true;
break;
}
}
if(isBreaking){
break;
}
}
}
}
하지만 저는 첫 번째 방법을 사용하는 것을 선호합니다.
데모:break,continue,그리고.label:
Java 키워드break그리고.continue디폴트값이 설정되어 있습니다."가장 가까운 루프"이며, 몇 년 동안 Java를 사용해 온 오늘, 이제서야 알게 되었습니다!
흔치 않은 사용인 것 같지만 유용해요.
import org.junit.Test;
/**
* Created by cui on 17-5-4.
*/
public class BranchLabel {
@Test
public void test() {
System.out.println("testBreak");
testBreak();
System.out.println("testBreakLabel");
testBreakLabel();
System.out.println("testContinue");
testContinue();
System.out.println("testContinueLabel");
testContinueLabel();
}
/**
testBreak
a=0,b=0
a=0,b=1
a=1,b=0
a=1,b=1
a=2,b=0
a=2,b=1
a=3,b=0
a=3,b=1
a=4,b=0
a=4,b=1
*/
public void testBreak() {
for (int a = 0; a < 5; a++) {
for (int b = 0; b < 5; b++) {
if (b == 2) {
break;
}
System.out.println("a=" + a + ",b=" + b);
}
}
}
/**
testContinue
a=0,b=0
a=0,b=1
a=0,b=3
a=0,b=4
a=1,b=0
a=1,b=1
a=1,b=3
a=1,b=4
a=2,b=0
a=2,b=1
a=2,b=3
a=2,b=4
a=3,b=0
a=3,b=1
a=3,b=3
a=3,b=4
a=4,b=0
a=4,b=1
a=4,b=3
a=4,b=4
*/
public void testContinue() {
for (int a = 0; a < 5; a++) {
for (int b = 0; b < 5; b++) {
if (b == 2) {
continue;
}
System.out.println("a=" + a + ",b=" + b);
}
}
}
/**
testBreakLabel
a=0,b=0,c=0
a=0,b=0,c=1
* */
public void testBreakLabel() {
anyName:
for (int a = 0; a < 5; a++) {
for (int b = 0; b < 5; b++) {
for (int c = 0; c < 5; c++) {
if (c == 2) {
break anyName;
}
System.out.println("a=" + a + ",b=" + b + ",c=" + c);
}
}
}
}
/**
testContinueLabel
a=0,b=0,c=0
a=0,b=0,c=1
a=1,b=0,c=0
a=1,b=0,c=1
a=2,b=0,c=0
a=2,b=0,c=1
a=3,b=0,c=0
a=3,b=0,c=1
a=4,b=0,c=0
a=4,b=0,c=1
*/
public void testContinueLabel() {
anyName:
for (int a = 0; a < 5; a++) {
for (int b = 0; b < 5; b++) {
for (int c = 0; c < 5; c++) {
if (c == 2) {
continue anyName;
}
System.out.println("a=" + a + ",b=" + b + ",c=" + c);
}
}
}
}
}
for (int j = 0; j < 5; j++) //inner loop로 대체해야 한다.for (int j = 0; j < 5 && !exitloops; j++).
이 경우 조건이 다음과 같은 경우 완전한 네스트된 루프가 종료됩니다.True하지만 만약 우리가exitloops상층부에만loop
for (int i = 0; i < 5 && !exitloops; i++) //upper loop
이 내부 루프를 종료하도록 통지하는 추가 플래그가 없기 때문에 내부 루프는 계속됩니다.
예: 만약
i = 3그리고.j=2그럼 조건은false하지만 다음 내부 루프의 반복에서는j=3그때의 조건(i*j)되세요9어느 것이true이너 루프는 다음 날까지j되세요5.
그래서, 그것은 반드시exitloops내부 루프도 마찬가지입니다.
boolean exitloops = false;
for (int i = 0; i < 5 && !exitloops; i++) { //here should exitloops as a Conditional Statement to get out from the loops if exitloops become true.
for (int j = 0; j < 5 && !exitloops; j++) { //here should also use exitloops as a Conditional Statement.
if (i * j > 6) {
exitloops = true;
System.out.println("Inner loop still Continues For i * j is => "+i*j);
break;
}
System.out.println(i*j);
}
}
@1800 INFORMATION 제안과 마찬가지로 내부 루프를 차단하는 조건을 외부 루프의 조건으로 사용합니다.
boolean hasAccess = false;
for (int i = 0; i < x && hasAccess == false; i++){
for (int j = 0; j < y; j++){
if (condition == true){
hasAccess = true;
break;
}
}
}
자바에는 C++와 같은 goto 기능이 없습니다.하지만 여전히,goto는 Java에서 예약된 키워드입니다.그들은 장래에 그것을 실행할지도 모른다.당신의 질문에 대한 답변은 자바에 라벨이라는 것이 있다는 것입니다.continue그리고.break진술.아래에서 코드를 찾습니다.
public static void main(String ...args) {
outerLoop: for(int i=0;i<10;i++) {
for(int j=10;j>0;j--) {
System.out.println(i+" "+j);
if(i==j) {
System.out.println("Condition Fulfilled");
break outerLoop;
}
}
}
System.out.println("Got out of the outer loop");
}
새로운 구현의 경우 if-else_if-else 문으로 논리를 고쳐 쓸 수 있습니다.
while(keep_going) {
if(keep_going && condition_one_holds) {
// Code
}
if(keep_going && condition_two_holds) {
// Code
}
if(keep_going && condition_three_holds) {
// Code
}
if(keep_going && something_goes_really_bad) {
keep_going=false;
}
if(keep_going && condition_four_holds) {
// Code
}
if(keep_going && condition_five_holds) {
// Code
}
}
그렇지 않으면 특별한 조건이 발생했을 때 플래그를 설정하고 각 루프 조건에서 플래그를 체크할 수 있습니다.
something_bad_has_happened = false;
while(something is true && !something_bad_has_happened){
// Code, things happen
while(something else && !something_bad_has_happened){
// Lots of code, things happens
if(something happened){
-> Then control should be returned ->
something_bad_has_happened=true;
continue;
}
}
if(something_bad_has_happened) { // The things below will not be executed
continue;
}
// Other things may happen here as well, but they will not be executed
// once control is returned from the inner cycle.
}
여기! 그래서 간단한 휴식은 효과가 없겠지만, 다음 방법으로 작동시킬 수 있습니다.continue.
단순히 하나의 프로그래밍 언어에서 Java로 로직을 포팅하고 동작시키기만 원한다면 라벨을 사용해 볼 수 있습니다.
내부 루프를 끊는 라벨만 사용하시면 됩니다.
public class Test {
public static void main(String[] args) {
outerloop:
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
break outerloop;
}
System.out.println(i + " " + j);
}
}
System.out.println("Done");
}
}
다음을 수행할 수 있습니다.
로컬 변수를 설정하다
false그 변수를 설정하다
true첫 번째 루프에서, 당신이 끊고 싶을 때그러면 외부 루프에서 조건이 설정되어 있는지 여부를 확인하고 외부 루프에서도 차단할 수 있습니다.
boolean isBreakNeeded = false; for (int i = 0; i < some.length; i++) { for (int j = 0; j < some.lengthasWell; j++) { //want to set variable if (){ isBreakNeeded = true; break; } if (isBreakNeeded) { break; //will make you break from the outer loop as well } }
언급URL : https://stackoverflow.com/questions/886955/how-do-i-break-out-of-nested-loops-in-java
'programing' 카테고리의 다른 글
| C에서 typedef와 typedef enum을 사용하려면 어떻게 해야 하나요? (0) | 2022.07.05 |
|---|---|
| 힙에 새 어레이를 생성하지 않고 Java에서 어레이 세그먼트 가져오기 (0) | 2022.07.04 |
| PWA Vuex 프로젝트에 파비콘을 바꿀 수 없습니다. (0) | 2022.07.04 |
| 계산된 속성 및 VueX를 사용한 스타일 바인딩 (0) | 2022.07.04 |
| 렌더링 후 Vue 구성 요소 이벤트 (0) | 2022.07.04 |