Я бы сделал это, используя комбинацию файлов cookie и флеш-файлов. Создайте GUID и сохраните его в файле cookie. Если файл cookie не существует, попробуйте прочитать его из файла cookie. Если он все еще не найден, создайте его и напишите в файл cookie. Таким образом, вы можете использовать один и тот же идентификатор GUID в браузерах.
Как и другие ответчики, я ' Я определенно предпочел бы поместить циклы в другой метод, после чего вы можете просто вернуться, чтобы полностью прекратить итерацию. Этот ответ просто показывает, как могут быть выполнены требования в вопросе.
Вы можете использовать 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
Я чувствую, что использование меток делает код очень похожим на оператор goto. Это всего лишь мысль.
Вместо этого бросьте исключение во внутренний цикл for
и инкапсулируйте два цикла for
с помощью блока try catch.
Что-то вроде
try {
// ...
for(Object outerForLoop : objectsOuter) {
// ...
for (Object innerForLoop : objectsInner) {
// ...
if (isConditionTrue)
throw new WrappedException("With some useful message. Probably some logging as well.");
}
}
catch (WrappedException) {
// Do something awesome or just don't do anything to swallow the exception.
}
Просто мысль. Я предпочитаю этот код, так как он дает мне лучшую возможность ведения журналов (как это слово) для меня, когда он запускается в производство или что-то в этом роде.
Вы просто используете метку для разрыва внутренних петель
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
}
}
Лучший и простой метод ..
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;
}
}
Если вам не нравятся break
s и goto
s, вы можете использовать «традиционный» цикл for вместо 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;
}
}
}
Вы можете использовать временную переменную:
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;
}
}
}
Вы можете использовать метки:
label1:
for (int i = 0;;) {
for (int g = 0;;) {
break label1;
}
}
Вы можете использовать именованный блок вокруг петель:
search: {
for (Type type : types) {
for (Type t : types2) {
if (some condition) {
// Do something and break...
break search;
}
}
}
}
Технически правильный ответ - обозначить внешнюю петлю. На практике, если вы хотите выйти в любой точке внутреннего цикла, вам лучше было бы перенести код в метод (статический метод, если это необходимо), а затем вызвать его.
Это окупится за удобочитаемость.
Код станет примерно таким:
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);
}
}
}
}
Java 8 Stream
решение:
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**/);
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);
}
}
Мне нужно было сделать похожую вещь, но я решил не использовать расширенный цикл for, чтобы сделать это.
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; }
}
Даже создание флага для внешнего цикла и проверка того, что после каждого выполнения внутреннего цикла может быть ответом.
Как это:
for (Type type : types) {
boolean flag=false;
for (Type t : types2) {
if (some condition) {
// Do something and break...
flag=true;
break; // Breaks out of the inner loop
}
}
if(flag)
break;
}
Концепция помеченного разрыва используется для разрыва вложенных циклов в Java, с помощью размеченного разрыва вы можете разорвать вложенность циклов в любой позиции. Пример 1:
loop1:
for(int i= 0; i<6; i++){
for(int j=0; j<5; j++){
if(i==3)
break loop1;
}
}
предположим, что есть 3 цикла, и вы хотите завершить цикл 3: Пример 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;
}
}
}
Я никогда не использую ярлыки. Кажется, это плохая практика. Вот что я бы сделал:
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;
}
}
}
Обычно в таких случаях это входит в сферу более значимой логики, скажем, некоторого поиска или манипулирования некоторыми итеративными объектами 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;
}
Основные минусы:
Плюсы:
Так что это просто обработка случай через другой подход.
В основном вопрос к автору этого вопроса: что вы думаете об этом подходе?
Демонстрация
public static void main(String[] args) {
outer:
while (true) {
while (true) {
break outer;
}
}
}
Используйте функцию:
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;
}
}
}
}
Это довольно просто в использовании 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;
}
}
}
}
Однако я предпочитаю использовать первый подход.