0
votes

Y a-t-il une meilleure façon d'écrire cette boucle?

J'ai besoin de vérifier si au moins 1 élément dans une liste a x, y et z (tout en même temps). par exemple. L'article 1 a x, et l'élément 2 a y et z.

Je pensais qu'il serait préférable de le faire sans créer de multiples boucles et de vérifier l'un d'entre eux, mais de stocker une variable, puis de le vérifier pour que cela puisse 't être réglé sur false à nouveau une fois vrai. P>

On dirait que je manque probablement une meilleure façon de le faire, alors y a-t-il un? p>

Merci P>

        boolean hasX = false;
        boolean hasY = false;
        boolean hasZ = false;

        for (ItemType item : Items) {
            if (!hasX) { hasX = DoesHaveX(item); }
            if (!hasY) { hasY = DoesHaveY(item); }
            if (!hasZ) { hasZ = DoesHaveZ(item); }
    }


8 commentaires

Désolé, oui, il est censé être transmis.


Vous pouvez BREAKE une fois que vous avez trouvé tous les 3, (et d'autres choses comme boutique dans un peu de place pour l'espace, Blah Blah). Mais je ne peux pas penser à une amélioration significative ici: /


Oui, bonne idée. Merci :)


Pareil ici. Ceci est directement en avant, ne pas trop penser.


Il existe un site spécifique pour la revue de code, codereview.stackexchange.com


@Joakimdanielson dans son formulaire actuel La question serait fermée dans un rythme cardiaque sur l'examen du code


Vous pouvez utiliser items.foreach (article -> {...}); , mais cela n'améliorerait rien, cela ne ferait que le faire dans un java-8-Way ...


Vous pouvez simplement mettre la logique pour vérifier avec le si à l'intérieur de la méthode newavex et le définit hasx en conséquence, au lieu d'avoir le logique dans la boucle.


4 Réponses :


0
votes

Une carte de flux / réduisez la version de la boucle pour le plaisir. Pas sûr s'il vaut mieux être honnête. Mais au moins nous nous débarrassons de toutes les variables

  • Carte Chaque élément à une liste de 3 booléens (un pour chaque attribut x, y, z)
  • Réduisez toute la liste dans une liste de 3 booléens (un pour chaque attribut X, Y, Z) Vérification si l'un des éléments a chaque valeur
  • Vérifiez que tous les éléments de la liste résultante sont VRAI. xxx

2 commentaires

Tellement d'allocations via arranges.aslist :(. Et arranges.Aslist (faux, faux, faux) est vraiment laid et inhabituel haha. Mais oui, une belle approche fonctionnelle


Oui, mais je ne sais pas si le flux l'optimise en interne. Nous devrions faire des tests pour cela. Sauf si quelqu'un sache.



0
votes

Voici une approche extensible qui utilise une énumération pour que vous ne puissiez jamais toucher la logique de HasoneoFall code> à nouveau. Il vous suffit d'étendre l'énumé donné.

import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

class StackOverflowQuestion56902308Scratch {
    class ItemType {
        boolean x;
        boolean y;
        boolean z;
    }

    enum ItemTypeCheck implements Predicate<ItemType> {
        HASX() {
            @Override
            public boolean test(ItemType itemType) {
                //TODO: implement me
                return itemType.x;
            }
        },
        HASY() {
            @Override
            public boolean test(ItemType itemType) {
                //TODO: implement me
                return itemType.y;
            }
        },
        HASZ() {
            @Override
            public boolean test(ItemType itemType) {
                //TODO: implement me
                return itemType.z;
            }
        }
    }

    public static boolean hasOneOfAll(List<ItemType> itemTypes) {
        Map<ItemTypeCheck, Boolean> result = new EnumMap<>(ItemTypeCheck.class);
        for (ItemType itemType : itemTypes) {
            for (ItemTypeCheck check : ItemTypeCheck.values()) {
                result.merge(check, check.test(itemType), Boolean::logicalOr);
            }
        }

        return result.values().stream().allMatch(hadOne -> hadOne);
    }

}


0 commentaires

1
votes

Si vous allez coller à un JVM en dessous de 1,8, votre code est tout à fait bien!

Peut-être que vous pourriez sauver peu d'opérations comme briser la boucle une fois que vous avez trouvé un match pour les trois booléens et ne vérifiant que ceux qui sont non trouvé encore. p> xxx pré>

Si vous n'êtes tout simplement bien d'utiliser des flux, il est préférable d'initialiser chacune des variables à sa création comme: P>

    boolean hasX = items.stream().anyMatch(this::doesHaveX); // goes trough the elements until a match is found.
    boolean hasY = items.stream().anyMatch(this::doesHaveY); // goes trough the elements until a match is found.
    boolean hasZ = items.stream().anyMatch(this::doesHaveZ); // goes trough the elements until a match is found.


2 commentaires

J'aime votre dernier exemple de code pour sa simplicité: il est évident que ce qui se passe. Il s'arrête même tôt quand il l'a déjà jugé match. Bien fait


Je pense que l'OP demande à la mauvaise question ici et, par conséquent, la réponse ne conviendra pas à ses attentes ... peut-être qu'il devra améliorer les abstractions qu'il est mise en œuvre jusqu'à présent pour obtenir un code qui va bien ...



0
votes

juste pour ajouter un bitset code> variante aussi, et sous l'hypothèse que la vérification a ... code> est une opération semi-coûteuse:

private static final int xBit = 0;
private static final int yBit = 1;
private static final int zBit = 2;

public static boolean hasAll(final Collection<ItemType> items) {
    if (items.isEmpty()) return false;

    final BitSet bits = new BitSet(3);

    for (final ItemType item : items) {

        // Check if bit is already set to avoid
        // needless `has*` evaluation
        if (!bits.get(xBit) && hasX(item)) bits.set(xBit);

        if (!bits.get(yBit) && hasY(item)) bits.set(yBit);

        if (!bits.get(zBit) && hasZ(item)) bits.set(zBit);

        // You could repeat this INSIDE all of the 'if's
        // above to potentially avoid computing bits.get
        // but I'd sacrifice that for the slightly improved
        // readability.
        if (bits.cardinality() == 3) return true;
    }

    return false;
}


0 commentaires