7
votes

Refacteur pour la boucle

J'ai une boucle foreach en Java (version simplifiée ici) xxx

existe-t-il un moyen automatisé de le refacturer sur un traditionnel pour

Je sais comment le faire manuellement xxx

Comme vous pouvez le constater, il y a un peu de dactylographie nécessaire dans le pour instruction " En plus d'introduire la variable nom à nouveau et attribuez-lui la valeur noms.get (i) . Au total, le manuel Modifier est trop sujet à une erreur pour moi.

Pourquoi est-ce que je veux faire cela? Je dois corriger un bogue et le correctif est de démarrer à l'index 1 au lieu d'index 0 et de fin à l'index N-1 au lieu de la fin (malheureusement, je ne peux pas corriger l'entrée immédiatement, j'ai besoin d'attendre une mise à jour de la bibliothèque. Si cela est reconnu comme un bug).

Qu'est-ce que j'ai essayé? J'ai cliqué sur le bouton droit de la souris sur le mot clé pour sur "Refactor", mais aussi loin que je peux obtenir des entrées de menu contextuel, rien de là ne ferait le travail pour moi. < P> Pourquoi je pense que cela pourrait théoriquement fonctionner? Comme une fonctionnalité similaire existe dans Resharper pour Visual Studio (C #).

FYI: J'utilise Eclipse Luna SR 2 (4.4.2)


3 commentaires

Est-il possible d'introduire une nouvelle méthode au lieu de «getNames» qui renvoie la liste sans premier et dernier élément?


@Devblanked: Bien sûr, cela serait techniquement possible, mais cela ne signifie pas que je veux écrire manuellement une boucle qui copie tout sauf le premier et le dernier article?


Pas vraiment, vous pouvez supprimer les premiers et derniers articles donnant à leurs index, docs.oracle.com/javase/7/docs/api/java/util/... .


7 Réponses :


0
votes

Soyez prudent avec ce refactoring.

La raison est que pour une liste liée traditionnelle, votre deuxième pour la formulation de boucle est O (n * n) car vous devez traverser la liste liée afin d'évaluer les noms .get (i); . Cela pourrait devenir cher.

Envisagez des implications de performance lors du déplacement de pour (nom de chaîne: noms) {. Il se peut que ce soit un meilleur moyen de résoudre votre bogue immédiat et de conserver le "Big O" actuel.

pour (nom de chaîne: noms.sublist (1, noms.size () - 1)) {

est une de ces voies (Acknowledge @JB NIZET).


1 commentaires

Bien que correct en principe, aucun programmeur sain n'utilise de toute façon. Il est avantage de O (1) Les coûts d'insertion ne paient que sur de telles recherches sur lesquelles son inconvénient de la consommation de mémoire à l'élément incroyablement plus élevée le rend inutilisable.



6
votes

Dans mon éclipse (Kepler RC2), il fonctionne pour sélectionner le mot-clé et utiliser le correctif rapide dans le menu contextuel ou frappez ctrl + 1 < / kbd> pour le raccourci. Eclipse m'offre ensuite "Convertir en indexé" pour "boucle" ou "Convertir à Itérateur basé sur" pour "boucle".

Capture d'écran d'options de correction rapide


0 commentaires

10
votes

Mouseover the pour instruction, clic droit, correction rapide ( ctrl + 1 ), convertir en boucle indexée.

devrait fonctionner!


2 commentaires

Appelez-le ensuite le Ctrl + 1 Action ... BTW, vous n'avez pas besoin de mettre en évidence la déclaration pour , le curseur en plus de cela suffit.


@Thomas, pour être précis Eclipse propose des "correctifs rapides" pour corriger les problèmes (erreurs / avertissements) et "assistance rapide" pour d'autres modifications typiques. La conversion en boucle est une "aide rapide". Seulement pour la commodité sont les deux actions liées à Ctrl-1 .



7
votes
List<String> names = fixList(getNames());
for(String name : names) {
    doSomething(name);
}

2 commentaires

Ok, pas exactement ce que j'ai demandé, mais certainement bien parce que si je reçois la mise à jour de la bibliothèque, il suffit de supprimer une ligne de code (faire le correctif).


Cela résout le problème que vous auriez eu si vous avez la réponse que vous recherchez :) Je changerais Fixlist à trimiste et ajouter des arguments beguindex et endindex rendant la fonction plus réutilisable.



-2
votes

Lorsque vous utilisez Java 8, vous pouvez utiliser l'API de flux

names.stream().skip(1).reverse().skip(1).reverse().foreach(
    name -> do something(name)
);


2 commentaires

Il n'y a pas de méthode inverse () sur le flux.


En outre que ce n'est pas ce que le questionneur a demandé; Il n'y a pas de inverse méthode sur flux et foreach ne respecte pas l'ordre source, donc foreachorded est nécessaire.



1
votes

Vous pouvez utiliser: xxx

ou en manuellement: xxx

mais le premier que je préfère utiliser.


0 commentaires

0
votes

Ne pas aller pour l'itération indexée! Cela ne fonctionne pas bien avec toutes les implémentations de la liste code>.

Il est beaucoup préférable d'aller pour un itérateur code> et permettez au JIT optimiser le itérateur code > Éloignez si ce code est chaud. p>

Donc, écrivez ceci: p> xxx pré>

ou que (une allocation moins): P>

Iterator<String> it = getNames().iterator();
it.next(); // You seem to be sure there is more than one element in the list
while (it.hasNext()) {
    String name = it.next();
    doSomething(name);
}


0 commentaires