目次
1. MyBatisは、複数のクエリ条件に対して1 = 1を書き込みません
2. entrySet()を繰り返して、マップのキーと値を取得します
3つ目は、Collection.isEmpty()を使用して空を検出する
第四に、コレクションを初期化するときにそのサイズを指定してみてください
6. Collection.containsメソッドを頻繁に呼び出す必要がある場合は、Setを使用します
7つ目は、静的コードブロックを使用して、静的メンバー変数の割り当てを実現することです。
8.未使用のローカル変数、メソッドパラメータ、プライベートメソッド、フィールド、および余分な括弧を削除します。
数か月間作業した後、コードが非常に不規則で、冗長性が多く、乱雑であると感じました。ターゲットを絞った方法でコード仕様を改善するにはどうすればよいですか。
標準コードの実際の動作を共有しましょう。
コードは666と書くことができますが、上司は弟子を受け入れることができますか?
1. MyBatisは、複数のクエリ条件に対して1 = 1を書き込みません
複数のクエリ条件が発生した場合、where 1 = 1を使用すると問題を簡単に解決できますが、「where 1 = 1」のフィルタ条件を追加した後、データベースシステムが追加されるため、パフォーマンスが大幅に低下する可能性があります。インデックスなどのクエリ最適化戦略を使用することはできません。データベースシステムは、データの各行をスキャンして(つまり、テーブル全体のスキャン)、この行がフィルタ条件を満たしているかどうかを比較する必要があります。テーブル内のデータ量が多い場合、クエリ速度は非常に遅くなります;さらに、SQLインジェクションのリスクがあります。
反例:
<select id="queryBookInfo" parameterType="com.tjt.platform.entity.BookInfo" resultType="java.lang.Integer">
select count(*) from t_rule_BookInfo t where 1=1
<if test="title !=null and title !='' ">
AND title = #{title}
</if>
<if test="author !=null and author !='' ">
AND author = #{author}
</if>
</select>
正例:
<select id="queryBookInfo" parameterType="com.tjt.platform.entity.BookInfo" resultType="java.lang.Integer">
select count(*) from t_rule_BookInfo t
<where>
<if test="title !=null and title !='' ">
title = #{title}
</if>
<if test="author !=null and author !='' ">
AND author = #{author}
</if>
</where>
</select>
同じことがUPDATE操作にも当てはまり、1 = 1の代わりにフラグを使用できます。
2. entrySet()を繰り返して、マップのキーと値を取得します
マップのプライマリキーキーのみをループで取得する必要がある場合、keySet()の繰り返しは正しいですが、プライマリキーキーと値の値が必要な場合、entrySet()の繰り返しは、keySet()の最初の繰り返しよりも効率的です。後で取得して値を取得することをお勧めします。
反例:
//Map 获取value 反例:
HashMap<String, String> map = new HashMap<>();
for (String key : map.keySet()){
String value = map.get(key);
}
正例:
//Map 获取key & value 正例:
HashMap<String, String> map = new HashMap<>();
for (Map.Entry<String,String> entry : map.entrySet()){
String key = entry.getKey();
String value = entry.getValue();
}
3つ目は、Collection.isEmpty()を使用して空を検出する
Collection.size()を使用して空かどうかを検出することは論理的に問題ありませんが、Collection.isEmpty()を使用すると、コードが読みやすくなり、パフォーマンスが向上します。さらに、Collection.isEmpty()の実装も時間の複雑さはO(1)であり、複数回ループする必要はありませんが、Collection.size()メソッドによって達成される時間の複雑さの一部はO(n)である可能性があります。
反例:
LinkedList<Object> collection = new LinkedList<>();
if (collection.size() == 0){
System.out.println("collection is empty.");
}
正例:
LinkedList<Object> collection = new LinkedList<>();
if (collection.isEmpty()){
System.out.println("collection is empty.");
}
//检测是否为null 可以使用CollectionUtils.isEmpty()
if (CollectionUtils.isEmpty(collection)){
System.out.println("collection is null.");
}
第四に、コレクションを初期化するときにそのサイズを指定してみてください
コレクションの各拡張の時間の複雑さはO(n)である可能性が高く、時間とパフォーマンスを消費するため、初期化中にコレクションのサイズを指定してください。これにより、コレクションの拡張の数を効果的に減らすことができます。
反例:
//初始化list,往list 中添加元素反例:
int[] arr = new int[]{1,2,3,4};
List<Integer> list = new ArrayList<>();
for (int i : arr){
list.add(i);
}
正例:
//初始化list,往list 中添加元素正例:
int[] arr = new int[]{1,2,3,4};
//指定集合list 的容量大小
List<Integer> list = new ArrayList<>(arr.length);
for (int i : arr){
list.add(i);
}
5、StringBuilderを使用して文字列を接続します
一般的な文字列スプライシングはコンパイル時にJavaによって最適化されますが、ループ内の文字列スプライシングはJavaコンパイル時に最適化できないため、置換にはStringBuilderを使用する必要があります。
反例:
//在循环中拼接字符串反例
String str = "";
for (int i = 0; i < 10; i++){
//在循环中字符串拼接Java 不会对其进行优化
str += i;
}
正例:
//在循环中拼接字符串正例
String str1 = "Love";
String str2 = "Courage";
String strConcat = str1 + str2; //Java 编译器会对该普通模式的字符串拼接进行优化
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++){
//在循环中,Java 编译器无法进行优化,所以要手动使用StringBuilder
sb.append(i);
}
6. Collection.containsメソッドを頻繁に呼び出す必要がある場合は、Setを使用します
Javaコレクションクラスライブラリでは、Listのcontainsメソッドの一般的な時間の複雑さはO(n)です。データを見つけるためにcontainsメソッドをコードで頻繁に呼び出す必要がある場合は、最初にコレクションリストをHashSet実装に変換し、O(n)の時間の複雑さを示します。 O(1)になります。
反例:
//频繁调用Collection.contains() 反例
List<Object> list = new ArrayList<>();
for (int i = 0; i <= Integer.MAX_VALUE; i++){
//时间复杂度为O(n)
if (list.contains(i))
System.out.println("list contains "+ i);
}
正例:
//频繁调用Collection.contains() 正例
List<Object> list = new ArrayList<>();
Set<Object> set = new HashSet<>();
for (int i = 0; i <= Integer.MAX_VALUE; i++){
//时间复杂度为O(1)
if (set.contains(i)){
System.out.println("list contains "+ i);
}
}
7つ目は、静的コードブロックを使用して、静的メンバー変数の割り当てを実現することです。
コレクションタイプの静的メンバー変数の場合、コレクション実装を使用して値を割り当てる代わりに、静的コードブロック割り当てを使用する必要があります。
反例:
//赋值静态成员变量反例
private static Map<String, Integer> map = new HashMap<String, Integer>(){
{
map.put("Leo",1);
map.put("Family-loving",2);
map.put("Cold on the out side passionate on the inside",3);
}
};
private static List<String> list = new ArrayList<>(){
{
list.add("Sagittarius");
list.add("Charming");
list.add("Perfectionist");
}
};
正例:
//赋值静态成员变量正例
private static Map<String, Integer> map = new HashMap<String, Integer>();
static {
map.put("Leo",1);
map.put("Family-loving",2);
map.put("Cold on the out side passionate on the inside",3);
}
private static List<String> list = new ArrayList<>();
static {
list.add("Sagittarius");
list.add("Charming");
list.add("Perfectionist");
}
8.未使用のローカル変数、メソッドパラメータ、プライベートメソッド、フィールド、および余分な括弧を削除します。
ツールクラスの9つのシールドコンストラクター
ユーティリティクラスは静的フィールドと関数のコレクションであり、インスタンス化しないでください。ただし、Javaは、明確に定義されたコンストラクターなしで、クラスごとに暗黙のパブリックコンストラクターを追加します。不要なインスタンス化を回避するには、この暗黙のパブリックコンストラクターを保護するために、プライベートコンストラクターを明示的に定義します。
反例:
public class PasswordUtils {
//工具类构造函数反例
private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);
public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";
public static String encryptPassword(String aPassword) throws IOException {
return new PasswordUtils(aPassword).encrypt();
}
正例:
public class PasswordUtils {
//工具类构造函数正例
private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);
//定义私有构造函数来屏蔽这个隐式公有构造函数
private PasswordUtils(){}
public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";
public static String encryptPassword(String aPassword) throws IOException {
return new PasswordUtils(aPassword).encrypt();
}
10、冗長な例外キャプチャを削除して実行します
catchステートメントで例外をキャッチした後、何も処理されない場合は、例外を再スローします。これは、例外をキャッチしないのと同じです。このコードを削除するか、他の処理を追加できます。
反例:
//多余异常反例
private static String fileReader(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;
}
}
正例:
//多余异常正例
private static String fileReader(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) {
return "fileReader exception";
}*/
}
}
記事はここで終わります
より標準化されたコードを書くために、Xiao Bianはここで、Alibaba開発のすべての人のためのハンドブックを準備します。小さな友達が、私が自由に選んだ ポイントを教えてくれる必要があります。
編集者の共有が気に入った場合は、気に入ってフォローすることができます。編集者は引き続き最新の記事を共有し、特典を受け取ります。