web-dev-qa-db-fra.com

boucle-while

Bien sûr, c’est une déclaration impossible en Java (à ce jour), mais dans l’idéal, j’aimerais l’implémenter, car elle est au cœur de nombreuses itérations. Par exemple, la première fois qu'il s'appelle, je le fais plus de 650 000 fois lorsqu'il crée la variable ArrayList. Malheureusement, mon code actuel ne contient pas la variable set dans la boucle else; ainsi, il passera sur les commandes add puis set et fera perdre du temps.

Après cela, je l'ai également dans une autre boucle où il effectue uniquement le jeu, car les données sont déjà créées et qui sont multi-imbriquées dans de nombreux autres, de sorte que le processus est long.

ArrayList<Integer>  dataColLinker = new Java.util.ArrayList<Integer>();
...
...
public void setLinkerAt( int value, int rowIndex) {
    ...
    while(rowIndex >= dataColLinker.size()) {
        dataColLinker.add(value);
    } else {
        dataColLinker.set(rowIndex, value);
    }

Des idées ou des théories?? Je ne suis pas sûr des vitesses en Java en ce qui concerne les instructions if et les commandes ArrayList, etc.

8
xchiltonx

Est-ce que je manque quelque chose?

Ce code hypothétique

while(rowIndex >= dataColLinker.size()) {
    dataColLinker.add(value);
} else {
    dataColLinker.set(rowIndex, value);
}

signifie la même chose que cela?

while(rowIndex >= dataColLinker.size()) {
    dataColLinker.add(value);
}
dataColLinker.set(rowIndex, value);

ou ca?

if (rowIndex >= dataColLinker.size()) {
    do {
        dataColLinker.add(value);
    } while(rowIndex >= dataColLinker.size());
} else {
    dataColLinker.set(rowIndex, value);
}

(Ce dernier a plus de sens ... je suppose). Quoi qu'il en soit, il est évident que vous pouvez réécrire la boucle de sorte que le "test else" ne se répète pas à l'intérieur de la boucle ... comme je viens de le faire.


FWIW, il s’agit très probablement d’une optimisation prématurée. En d’autres termes, vous perdez probablement votre temps à optimiser un code qui n’a pas besoin d’être optimisé:

  • Pour autant que vous sachiez, l'optimiseur du compilateur JIT a peut-être déjà déplacé le code afin que la partie "else" ne soit plus dans la boucle.

  • Même si ce n’est pas le cas, il est fort probable que la chose que vous essayez d’optimiser ne constitue pas un goulot d’étranglement important ... même si elle peut être exécutée 600 000 fois.

Mon conseil est d’oublier ce problème pour le moment. Faites fonctionner le programme. Quand cela fonctionne, décidez si cela fonctionne assez vite. Sinon, profilez-le et utilisez la sortie du profileur pour décider où il vaut la peine de consacrer votre temps à l'optimisation.

18
Stephen C

Je ne vois pas pourquoi il y a une encapsulation d'un moment ...

Utilisation

//Use the appropriate start and end...
for(int rowIndex = 0, e = 65536; i < e; ++i){        
    if(rowIndex >= dataColLinker.size()) {
         dataColLinker.add(value);
     } else {
        dataColLinker.set(rowIndex, value);
     }    
}
3
Jay

Enveloppez l'instruction "set" pour signifier "set if not set" et mettez-la nue au-dessus de la boucle while.

Vous avez raison, le langage ne fournit pas exactement ce que vous recherchez dans cette syntaxe, mais c'est parce qu'il existe des paradigmes de programmation comme celui que je viens de suggérer, vous n'avez donc pas besoin de la syntaxe que vous proposez.

1
djechlin
boolean entered = false, last;
while ( (entered |= last = ( condition )) && last ) {
        // Do while
} if ( !entered ) {
        // Else
}

Vous êtes le bienvenu. 

Exemple: 

boolean entered = false, last;
while ( (entered |= last = (atomic.get() > 3 && !status.destroyed()) && so on) && last ) {
        // Do while
} if ( !entered ) {
        // Else
}
0
momomo

En supposant que vous venez de Python et acceptez cela comme la même chose:

def setLinkerAt(value, rowIndex):
    isEnough = lambda i: return i < dataColLinker.count()
    while (not isEnough(rowIndex)):
        dataColLinker.append(value)
    else:
        dataColLinker[rowIndex] = value 

Le plus similaire que je pouvais trouver était:

public void setLinkerAt( int value, int rowIndex) {
    isEnough = (i) -> { return i < dataColLine.size; }
    if(isEnough()){
        dataColLinker.set(rowIndex, value);
    }
    else while(!isEnough(rowInex)) {
        dataColLinker.add(value);
    }

Notez la nécessité de la logique et de la logique inverse. Je ne suis pas sûr que ce soit une excellente solution (duplication de la logique), mais _else sans support est la syntaxe la plus proche à laquelle je puisse penser, tout en maintenant le même acte consistant à ne pas exécuter la logique plus que nécessaire.

0
Jefferey Cave

Cette instruction while ne devrait exécuter le code else que lorsque la condition est fausse, cela signifie qu'elle l'exécutera toujours. Mais il y a un problème: lorsque vous utilisez le mot clé break dans la boucle while, l'instruction else ne doit pas s'exécuter.

Le code qui satisfait la condition est seulement:

boolean entered = false;
while (condition) {
   entered = true; // Set it to true stright away
   // While loop code


   // If you want to break out of this loop
   if (condition) {
      entered = false;
      break;
   }
} if (!entered) {
   // else code
}
0
Kamil B

Java n'a pas cette structure de contrôle.
Il convient cependant de noter que d’autres langues le font.
Python par exemple, a la construction While-else

Dans le cas de Java, vous pouvez imiter ce comportement comme vous l'avez déjà montré: 

if (rowIndex >= dataColLinker.size()) {
    do {
        dataColLinker.add(value);
    } while(rowIndex >= dataColLinker.size());
} else {
    dataColLinker.set(rowIndex, value);
}
0
Trevor Hickey