[JAVA] [Mise en œuvre] Éliminez l'odeur inquiétante du code

1. Performance

1-1. Utilisez entrySet () pour obtenir la clé et la valeur de Map

bad.java


Map<String, String> map = ...;
for (String key : map.keySet()) {
    String value = map.get(key);
    ...
}

good.java


Map<String, String> map = ...;
for (Map.Entry<String, String> entry : map.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue();
    ...
}

1-2. Utilisez Collection.isEmpty ()

bad.java


if (collection.size() == 0) {
    ...
}

good.java


if (collection.isEmpty()) {
    ...
}

1-3 Assemblage Ne vous installez pas.

bad.java


List<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
if (list.containsAll(list)) { //Cela n'a pas de sens, c'est vrai.
    ...
}
list.removeAll(list); //Mauvaise performance, clair()utilisation.

1-4. Spécifiez la taille autant que possible lors de l'initialisation de l'ensemble.

bad.java


int[] arr = new int[]{1, 2, 3};
List<Integer> list = new ArrayList<>();
for (int i : arr) {
    list.add(i);
}

good.java


int[] arr = new int[]{1, 2, 3};
List<Integer> list = new ArrayList<>(arr.length);
for (int i : arr) {
    list.add(i);
}

1-5. Concaténez les chaînes avec StringBuilder.

bad.java


String s = "";
for (int i = 0; i < 10; i++) {
    s += i;
}

good.java


String a = "a";
String b = "b";
String c = "c";
String s = a + b + c; //Pas de problème, le compilateur java peut être optimisé
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
    sb.append(i);  //Utilisez StringBuilder manuel car le compilateur java ne peut pas être optimisé à l'intérieur de la boucle
}

1-6. Renvoie un élément aléatoire dans la liste

good.java


List<Integer> list = otherService.getList();
if (list instanceof RandomAccess) {
    //En interne, il est réalisé par un tableau, il peut donc être randomisé
    System.out.println(list.get(list.size() - 1));
} else {
    //Mauvaises performances pouvant être obtenues en interne avec une liste de liens
}

1-7. Utilisez Set si vous pouvez appeler fréquemment la méthode Collection.contains

bad.java


ArrayList<Integer> list = otherService.getList();
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
    //Complexité temporelle O(n)
    list.contains(i);
}

good.java


ArrayList<Integer> list = otherService.getList();
Set<Integer> set = new HashSet(list);
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
    //Complexité temporelle O(1)
    set.contains(i);
}

2. Code élégant

2-1. Ajouter le L supérieur après une longue constante

bad.java


long value = 1l;
long max = Math.max(1L, 5);

good.java


long value = 1L;
long max = Math.max(1L, 5L);

2-2. N'utilisez pas de nombres magiques

bad.java


for (int i = 0; i < 100; i++){
    ...
}
if (a == 100) {
    ...
}

good.java


private static final int MAX_COUNT = 100;
for (int i = 0; i < MAX_COUNT; i++){
    ...
}
if (count == MAX_COUNT) {
    ...
}

2-3. N'attribuez pas de variables membres statiques dans la collection

bad.java


private static Map<String, Integer> map = new HashMap<String, Integer>() {
    {
        put("a", 1);
        put("b", 2);
    }
};

private static List<String> list = new ArrayList<String>() {
    {
        add("a");
        add("b");
    }
};

good.java


private static Map<String, Integer> map = new HashMap<>();
static {
    map.put("a", 1);
    map.put("b", 2);
};

private static List<String> list = new ArrayList<>();
static {
    list.add("a");
    list.add("b");
};

2-4.essai-avec-ressources recommandé

bad.java


private void handle(String fileName) {
    BufferedReader reader = null;
    try {
        String line;
        reader = new BufferedReader(new FileReader(fileName));
        while ((line = reader.readLine()) != null) {
            ...
        }
    } catch (Exception e) {
        ...
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                ...
            }
        }
    }
}

good.java


private void handle(String fileName) {
    try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
        String line;
        while ((line = reader.readLine()) != null) {
            ...
        }
    } catch (Exception e) {
        ...
    }
}

2-5. Supprimer les membres et les méthodes inutilisés

bad.java


public class DoubleDemo1 {
    private int unusedField = 100;
    private void unusedMethod() {
        ...
    }
    public int sum(int a, int b) {
        return a + b;
    }
}

good.java


public class DoubleDemo1 {
    public int sum(int a, int b) {
        return a + b;
    }
}

2-6. Supprimer les variables locales inutilisées

bad.java


public int sum(int a, int b) {
    int c = 100;
    return a + b;
}

good.java


public int sum(int a, int b) {
    return a + b;
}

2-7. Supprimer l'argument de la méthode inutilisée

bad.java


public int sum(int a, int b, int c) {
    return a + b;
}

good.java


public int sum(int a, int b) {
    return a + b;
}

2-8. Supprimer les parenthèses supplémentaires Supprimer

bad.java


return (x);
return (x + 2);
int x = (y * 3) + 1;
int m = (n * 4 + 2);

good.java


return x;
return x + 2;
int x = y * 3 + 1;
int m = n * 4 + 2;

2-9 Les constructeurs de classes utilitaires doivent être bloqués.

bad.java


public class MathUtils {
    public static final double PI = 3.1415926D;
    public static int sum(int a, int b) {
        return a + b;
    }
}

good.java


public class MathUtils {
    public static final double PI = 3.1415926D;
    private MathUtils() {}
    public static int sum(int a, int b) {
        return a + b;
    }
}

2-10. Supprimer les captures et les levées d'exceptions redondantes

bad.java


private static String readFile(String fileName) throws IOException {
    try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
        String line;
        StringBuilder builder = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }
        return builder.toString();
    } catch (Exception e) {
        throw e;
    }
}

good.java


private static String readFile(String fileName) throws IOException {
    try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
        String line;
        StringBuilder builder = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }
        return builder.toString();
    }
}

2-11 Les constantes statiques publiques doivent être accessibles via la classe.

bad.java


public class User {
    public static final String CONST_NAME = "name";
    ...
}

User user = new User();
String nameKey = user.CONST_NAME;

good.java


public class User {
    public static final String CONST_NAME = "name";
    ...
}

String nameKey = User.CONST_NAME;

2-12. Ne jugez pas nul par "exception de pointeur nul".

bad.java


public String getUserName(User user) {
    try {
        return user.getName();
    } catch (NullPointerException e) {
        return null;
    }
}

good.java


public String getUserName(User user) {
    if (Objects.isNull(user)) {
        return null;
    }
    return user.getName();
}

Utilisez 2-13.String.valueOf au lieu de "" + value.

bad.java


int i = 1;
String s = "" + i;

good.java


int i = 1;
String s = String.valueOf(i);

2-14. Ajoutez le commentaire @Deprecated au code obsolète.

good.java


/**
 *sauvegarder
 *
 * @obsolète car cette méthode est inefficace@link newSave()Utilisez la méthode pour le remplacer.
 */
@Deprecated
public void save(){
    // do something
}

3. Gardez le code à l'écart des bogues

3-1. Interdire l'utilisation du constructeur BigDecimal (double)

bad.java


BigDecimal value = new BigDecimal(0.1D); // 0.100000000000000005551115...

good.java


BigDecimal value = BigDecimal.valueOf(0.1D);; // 0.1

3-2. Renvoie un tableau vide et une collection vide. Ce n'est pas nul.

bad.java


public static Result[] getResults() {
    return null;
}

public static List<Result> getResultList() {
    return null;
}

public static Map<String, Result> getResultMap() {
    return null;
}

public static void main(String[] args) {
    Result[] results = getResults();
    if (results != null) {
        for (Result result : results) {
            ...
        }
    }

    List<Result> resultList = getResultList();
    if (resultList != null) {
        for (Result result : resultList) {
            ...
        }
    }

    Map<String, Result> resultMap = getResultMap();
    if (resultMap != null) {
        for (Map.Entry<String, Result> resultEntry : resultMap) {
            ...
        }
    }
}

good.java


public static Result[] getResults() {
    return new Result[0];
}

public static List<Result> getResultList() {
    return Collections.emptyList();
}

public static Map<String, Result> getResultMap() {
    return Collections.emptyMap();
}

public static void main(String[] args) {
    Result[] results = getResults();
    for (Result result : results) {
        ...
    }

    List<Result> resultList = getResultList();
    for (Result result : resultList) {
        ...
    }

    Map<String, Result> resultMap = getResultMap();
    for (Map.Entry<String, Result> resultEntry : resultMap) {
        ...
    }
}

3-3 Appelez la méthode equals qui utilise préférentiellement des constantes ou des valeurs déterminées.

bad.java


public void isFinished(OrderStatus status) {
    return status.equals(OrderStatus.FINISHED); //Peut être une exception de pointeur nul
}

good.java


public void isFinished(OrderStatus status) {
    return OrderStatus.FINISHED.equals(status);
}

public void isFinished(OrderStatus status) {
    return Objects.equals(status, OrderStatus.FINISHED);
}

3-4. Les champs d'attribut répertoriés doivent être privés et immuables

bad.java


public enum UserStatus {
    DISABLED(0, "Invalide"),
    ENABLED(1, "Efficacité");

    public int value;
    private String description;

    private UserStatus(int value, String description) {
        this.value = value;
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

good.java


public enum UserStatus {
    DISABLED(0, "Invalide"),
    ENABLED(1, "Efficacité");

    private final int value;
    private final String description;

    private UserStatus(int value, String description) {
        this.value = value;
        this.description = description;
    }

    public int getValue() {
        return value;
    }

    public String getDescription() {
        return description;
    }
}

3-5. Attention String.split (String regex)

bad.java


"a.ab.abc".split("."); //Le résultat est[]
"a|ab|abc".split("|"); //Le résultat est["a", "|", "a", "b", "|", "a", "b", "c"]

good.java


"a.ab.abc".split("\\."); //Le résultat est["a", "ab", "abc"]
"a|ab|abc".split("\\|"); //Le résultat est["a", "ab", "abc"]

Postscript

Référence Traduit de Alibaba Developer District

Recommended Posts

[Mise en œuvre] Éliminez l'odeur inquiétante du code
RSpec-Résultats de la révision du code de test pour la «validation des utilisateurs»
[Ruby] Code pour afficher le jour
Une revue du code utilisé par les rails débutants
Implémentez iOS14 UICollectionView avec le code minimum requis.
Le monde de Clara-Rules (2)
Implémentation de la fonction de recherche
Jugement du calendrier
Le monde de Clara-Rules (1)
Le monde de Clara-Rules (3)
Implémentation appliquée de l'espace de chat
L'idée du tri rapide
Mise en œuvre de la fonction de pagénation
L'idée de jQuery
[Java] Simplifiez la mise en œuvre de la gestion de l'historique des données avec Reladomo
Le piège que l'implémentation par défaut de l'interface Java 8 apporte
Spécifiez le code de caractère de la source lors de la construction avec Maven