3分钟速读原著-《Effective Java》(四)
2023-12-08 18:59:00
在编程中,我们经常会遇到一些重复性的代码,这些代码往往会使我们的程序难以阅读和维护。为了解决这个问题,我们可以使用一些设计模式来重构我们的代码,从而提高代码的可读性和可维护性。
在《Effective Java》一书中,作者Joshua Bloch提出了36条编程技巧,这些技巧可以帮助我们编写出更清晰、更易维护的Java代码。在本文中,我们将探讨Effective Java第四部分的编程技巧,包括使用实例域代替序数、使用EnumSet代替位域、使用EnumMap代替枚举当中的数组等。
使用实例域代替序数
在Java中,我们可以使用序数来表示枚举值。例如,我们可以使用以下代码来定义一个枚举类型:
public enum Color {
RED,
GREEN,
BLUE
}
如果我们想要获取枚举值的序数,我们可以使用ordinal()方法。例如,我们可以使用以下代码来获取Color.RED的序数:
Color.RED.ordinal() // 0
但是,使用序数来表示枚举值并不是一个好习惯。因为序数是枚举值在枚举类型中的位置,它可能会随着枚举类型的改变而改变。例如,如果我们向Color枚举类型中添加了一个新的枚举值,那么Color.RED的序数就会从0变为1。
为了避免这种情况,我们可以使用实例域来表示枚举值。例如,我们可以使用以下代码来定义一个枚举类型:
public enum Color {
RED(0),
GREEN(1),
BLUE(2);
private final int value;
private Color(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
使用实例域来表示枚举值,可以保证枚举值的唯一性,不会随着枚举类型的改变而改变。
使用EnumSet代替位域
在Java中,我们可以使用位域来表示一组标志。例如,我们可以使用以下代码来定义一个位域:
public class Flags {
public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLUE = 4;
}
如果我们想要设置一个标志,我们可以使用以下代码:
int flags = Flags.RED | Flags.GREEN; // 3
如果我们想要检查一个标志是否被设置,我们可以使用以下代码:
(flags & Flags.RED) != 0 // true
但是,使用位域来表示一组标志并不是一个好习惯。因为位域是使用二进制位来表示的,它很难阅读和理解。例如,如果我们想要知道Flags.RED和Flags.GREEN的组合是什么,我们需要进行以下计算:
Flags.RED | Flags.GREEN // 3
为了避免这种情况,我们可以使用EnumSet来表示一组标志。例如,我们可以使用以下代码来定义一个EnumSet:
import java.util.EnumSet;
public class Flags {
public static final EnumSet<Color> RED = EnumSet.of(Color.RED);
public static final EnumSet<Color> GREEN = EnumSet.of(Color.GREEN);
public static final EnumSet<Color> BLUE = EnumSet.of(Color.BLUE);
}
如果我们想要设置一个标志,我们可以使用以下代码:
EnumSet<Color> flags = EnumSet.of(Color.RED, Color.GREEN);
如果我们想要检查一个标志是否被设置,我们可以使用以下代码:
flags.contains(Color.RED) // true
使用EnumSet来表示一组标志,可以使我们的代码更加清晰和易于理解。
使用EnumMap代替枚举当中的数组
在Java中,我们可以使用枚举当中的数组来存储数据。例如,我们可以使用以下代码来定义一个枚举当中的数组:
public enum Color {
RED,
GREEN,
BLUE;
private String[] values = new String[3];
public void setValue(int index, String value) {
values[index] = value;
}
public String getValue(int index) {
return values[index];
}
}
如果我们想要设置一个值,我们可以使用以下代码:
Color.RED.setValue(0, "红色");
如果我们想要获取一个值,我们可以使用以下代码:
Color.RED.getValue(0) // "红色"
但是,使用枚举当中的数组来存储数据并不是一个好习惯。因为枚举当中的数组是静态的,它不能随着枚举类型的改变而改变。例如,如果我们向Color枚举类型中添加了一个新的枚举值,那么Color.RED的数组大小就会从3变为4。
为了避免这种情况,我们可以使用EnumMap来存储数据。例如,我们可以使用以下代码来定义一个EnumMap:
import java.util.EnumMap;
public class Color {
private static final EnumMap<Color, String> values = new EnumMap<>(Color.class);
public static void setValue(Color color, String value) {
values.put(color, value);
}
public static String getValue(Color color) {
return values.get(color);
}
}
如果我们想要设置一个值,我们可以使用以下代码:
Color.setValue(Color.RED, "红色");
如果我们想要获取一个值,我们可以使用以下代码:
Color.getValue(Color.RED) // "红色"
使用EnumMap来存储数据,可以使我们的代码更加清晰和易于维护。
小结
在本文中,我们探讨了Effective Java第四部分的编程技巧,包括使用实例域代替序数、使用EnumSet代替位域、使用EnumMap代替枚举当中的数组等。这些技巧可以帮助我们编写出更清晰、更易维护的Java代码。