1)根據給定日期,返回當月的第一天和最后一天的日期,出參使用日期數組。
2)根據給定日期,返回去年當月的第一天和最后一天的日期,出參使用日期數組。
3)根據給定日期,返回當年的第一天和最后一天的日期,出參使用日期數組。
4)根據給定日期,返回去年的第一天和最后一天的日期,出參使用日期數組。

1)DeepSeek-Coder-33B-Instruct生成的代碼:

package ai.deepseek;

import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.TemporalAdjusters;

public class DateUtils {

public static LocalDate[] getCurrentMonthStartAndEnd(LocalDate date) {
YearMonth yearMonth = YearMonth.from(date);
LocalDate firstDayOfMonth = yearMonth.atDay(1);
LocalDate lastDayOfMonth = yearMonth.atEndOfMonth();
return new LocalDate[]{firstDayOfMonth, lastDayOfMonth};
}

public static LocalDate[] getLastYearSameMonthStartAndEnd(LocalDate date) {
LocalDate lastYearDate = date.minusYears(1);
return getCurrentMonthStartAndEnd(lastYearDate);
}

public static LocalDate[] getCurrentYearStartAndEnd(LocalDate date) {
LocalDate firstDayOfYear = date.with(TemporalAdjusters.firstDayOfYear());
LocalDate lastDayOfYear = date.with(TemporalAdjusters.lastDayOfYear());
return new LocalDate[]{firstDayOfYear, lastDayOfYear};
}

public static LocalDate[] getLastYearStartAndEnd(LocalDate date) {
LocalDate lastYearDate = date.minusYears(1);
return getCurrentYearStartAndEnd(lastYearDate);
}

public static void main(String[] args) {
LocalDate currentDate = LocalDate.now();

LocalDate[] currentMonthDates = getCurrentMonthStartAndEnd(currentDate);
System.out.println("Current month start: " + currentMonthDates[0]);
System.out.println("Current month end: " + currentMonthDates[1]);

LocalDate[] lastYearSameMonthDates = getLastYearSameMonthStartAndEnd(currentDate);
System.out.println("Last year same month start: " + lastYearSameMonthDates[0]);
System.out.println("Last year same month end: " + lastYearSameMonthDates[1]);

LocalDate[] currentYearDates = getCurrentYearStartAndEnd(currentDate);
System.out.println("Current year start: " + currentYearDates[0]);
System.out.println("Current year end: " + currentYearDates[1]);

LocalDate[] lastYearDates = getLastYearStartAndEnd(currentDate);
System.out.println("Last year start: " + lastYearDates[0]);
System.out.println("Last year end: " + lastYearDates[1]);
}
}

運行的結果正確。

Current month start: 2024-02-01
Current month end: 2024-02-29
Last year same month start: 2023-02-01
Last year same month end: 2023-02-28
Current year start: 2024-01-01
Current year end: 2024-12-31
Last year start: 2023-01-01
Last year end: 2023-12-31

測評分析:

加分項:生成的代碼能正確編譯;運行結果正確;在原方法基礎上提煉出了可復用的方法;

減分項:方法命名有點中國式英文的風格,不夠優雅;代碼沒有注釋;

評分:80分。

2)CodeLlama-70B-Instruct生成的代碼:

package ai.codellama70b;

import java.time.LocalDate;
import java.time.Month;
import java.time.Year;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Arrays;

public class DateUtils {

public static LocalDate[] getFirstAndLastDayOfMonth(LocalDate date) {
LocalDate firstDay = date.withDayOfMonth(1);
LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
return new LocalDate[]{firstDay, lastDay};
}

public static LocalDate[] getFirstAndLastDayOfLastYearMonth(LocalDate date) {
YearMonth yearMonth = YearMonth.from(date).minusYears(1);
LocalDate firstDay = yearMonth.atDay(1);
LocalDate lastDay = yearMonth.atEndOfMonth();
return new LocalDate[]{firstDay, lastDay};
}

public static LocalDate[] getFirstAndLastDayOfYear(LocalDate date) {
Year year = Year.from(date);
LocalDate firstDay = year.atDay(1);
LocalDate lastDay = year.atDay(year.length());
return new LocalDate[]{firstDay, lastDay};
}

public static LocalDate[] getFirstAndLastDayOfLastYear(LocalDate date) {
Year year = Year.from(date).minusYears(1);
LocalDate firstDay = year.atDay(1);
LocalDate lastDay = year.atDay(year.length());
return new LocalDate[]{firstDay, lastDay};
}

public static void main(String[] args) {
LocalDate date = LocalDate.now();
System.out.println("First and last day of month: " + Arrays.toString(getFirstAndLastDayOfMonth(date)));
System.out.println("First and last day of last year month: " + Arrays.toString(getFirstAndLastDayOfLastYearMonth(date)));
System.out.println("First and last day of year: " + Arrays.toString(getFirstAndLastDayOfYear(date)));
System.out.println("First and last day of last year: " + Arrays.toString(getFirstAndLastDayOfLastYear(date)));
}
}

運行結果正確。

First and last day of month: [2024-02-01, 2024-02-29]
First and last day of last year month: [2023-02-01, 2023-02-28]
First and last day of year: [2024-01-01, 2024-12-31]
First and last day of last year: [2023-01-01, 2023-12-31]

測評分析:加分項:運行正確;方法命名較好;減分項:生成的代碼需要增加”import java.time.temporal.TemporalAdjusters;”才能編譯通過;代碼沒有做到復用;代碼沒有注釋;評分:60分

3)GLM-4

生成的代碼:

package ai.glm4;

import java.time.LocalDate;

public class DateUtils {

public static void main(String[] args) {
LocalDate currentDate = LocalDate.now(); // 當前日期
System.out.println("當前日期: " + currentDate);

// 測試第一個方法
LocalDate[] currentMonthDates = getFirstAndLastDayOfCurrentMonth(currentDate);
System.out.println("當月第一天: " + currentMonthDates[0] + ", 當月最后一天: " + currentMonthDates[1]);

// 測試第二個方法
LocalDate[] lastYearCurrentMonthDates = getFirstAndLastDayOfLastYearMonth(currentDate);
System.out.println("去年當月第一天: " + lastYearCurrentMonthDates[0] + ", 去年當月最后一天: " + lastYearCurrentMonthDates[1]);

// 測試第三個方法
LocalDate[] currentYearDates = getFirstAndLastDayOfCurrentYear(currentDate);
System.out.println("當年第一天: " + currentYearDates[0] + ", 當年最后一天: " + currentYearDates[1]);

// 測試第四個方法
LocalDate[] lastYearDates = getFirstAndLastDayOfLastYear(currentDate);
System.out.println("去年第一天: " + lastYearDates[0] + ", 去年最后一天: " + lastYearDates[1]);
}

// 方法1:根據給定日期,返回當月的第一天和最后一天的日期
public static LocalDate[] getFirstAndLastDayOfCurrentMonth(LocalDate date) {
LocalDate firstDayOfMonth = date.withDayOfMonth(1);
LocalDate lastDayOfMonth = date.withDayOfMonth(date.lengthOfMonth());
return new LocalDate[]{firstDayOfMonth, lastDayOfMonth};
}

// 方法2:根據給定日期,返回去年當月的第一天和最后一天的日期
public static LocalDate[] getFirstAndLastDayOfLastYearMonth(LocalDate date) {
LocalDate firstDayOfLastYearMonth = date.minusYears(1).withDayOfMonth(1);
LocalDate lastDayOfLastYearMonth = firstDayOfLastYearMonth.withDayOfMonth(firstDayOfLastYearMonth.lengthOfMonth());
return new LocalDate[]{firstDayOfLastYearMonth, lastDayOfLastYearMonth};
}

// 方法3:根據給定日期,返回當年的第一天和最后一天的日期
public static LocalDate[] getFirstAndLastDayOfCurrentYear(LocalDate date) {
LocalDate firstDayOfYear = date.withDayOfYear(1);
LocalDate lastDayOfYear = date.withDayOfYear(date.lengthOfYear());
return new LocalDate[]{firstDayOfYear, lastDayOfYear};
}

// 方法4:根據給定日期,返回去年的第一天和最后一天的日期
public static LocalDate[] getFirstAndLastDayOfLastYear(LocalDate date) {
LocalDate firstDayOfLastYear = date.minusYears(1).withDayOfYear(1);
LocalDate lastDayOfLastYear = firstDayOfLastYear.withDayOfYear(firstDayOfLastYear.lengthOfYear());
return new LocalDate[]{firstDayOfLastYear, lastDayOfLastYear};
}
}

運行結果正確。

當前日期: 2024-02-03
當月第一天: 2024-02-01, 當月最后一天: 2024-02-29
去年當月第一天: 2023-02-01, 去年當月最后一天: 2023-02-28
當年第一天: 2024-01-01, 當年最后一天: 2024-12-31
去年第一天: 2023-01-01, 去年最后一天: 2023-12-31

測評分析:

加分項:代碼編譯正確;運行結果正確;方法命名較好;提供了清晰的中文注釋;

減分項:沒有實現復用;

評分:90分。

4)GPT-3.5

生成的代碼:

package ai.gpt35;

import java.time.LocalDate;

public class DateRangeCalculator {

public static void main(String[] args) {
LocalDate currentDate = LocalDate.now();

// Test case 1
LocalDate[] currentMonthRange = getMonthRange(currentDate);
System.out.println("Current Month Range: " + currentMonthRange[0] + " to " + currentMonthRange[1]);

// Test case 2
LocalDate[] lastYearMonthRange = getLastYearMonthRange(currentDate);
System.out.println("Last Year's Current Month Range: " + lastYearMonthRange[0] + " to " + lastYearMonthRange[1]);

// Test case 3
LocalDate[] currentYearRange = getYearRange(currentDate);
System.out.println("Current Year Range: " + currentYearRange[0] + " to " + currentYearRange[1]);

// Test case 4
LocalDate[] lastYearRange = getLastYearRange(currentDate);
System.out.println("Last Year Range: " + lastYearRange[0] + " to " + lastYearRange[1]);
}

// Method 1: Get current month's first and last day
public static LocalDate[] getMonthRange(LocalDate date) {
LocalDate firstDay = date.withDayOfMonth(1);
LocalDate lastDay = date.withDayOfMonth(date.lengthOfMonth());
return new LocalDate[]{firstDay, lastDay};
}

// Method 2: Get last year's current month's first and last day
public static LocalDate[] getLastYearMonthRange(LocalDate date) {
LocalDate lastYearDate = date.minusYears(1);
return getMonthRange(lastYearDate);
}

// Method 3: Get current year's first and last day
public static LocalDate[] getYearRange(LocalDate date) {
LocalDate firstDay = date.withDayOfYear(1);
LocalDate lastDay = date.withDayOfYear(date.lengthOfYear());
return new LocalDate[]{firstDay, lastDay};
}

// Method 4: Get last year's first and last day
public static LocalDate[] getLastYearRange(LocalDate date) {
LocalDate lastYearDate = date.minusYears(1);
return getYearRange(lastYearDate);
}
}

運行結果正確。

Current Month Range: 2024-02-01 to 2024-02-29
Last Year's Current Month Range: 2023-02-01 to 2023-02-28
Current Year Range: 2024-01-01 to 2024-12-31
Last Year Range: 2023-01-01 to 2023-12-31

測評分析結果:加分項:編譯正確;運行結果正確;類命名比較好;抽象了公共方法,實現代碼復用;提供了注釋;減分項:方法命名有點中式英文;只提供了英文注釋;評分:90分。

5)GPT-4-0613

生成的代碼:

package ai.gpt4;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtils {

// 方法1:返回當月的第一天和最后一天的日期
public static Date[] getFirstAndLastDayOfMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, 1);
Date firstDayOfMonth = calendar.getTime();

calendar.add(Calendar.MONTH, 1);
calendar.add(Calendar.DAY_OF_MONTH, -1);
Date lastDayOfMonth = calendar.getTime();

return new Date[]{firstDayOfMonth, lastDayOfMonth};
}

// 方法2:返回去年當月的第一天和最后一天的日期
public static Date[] getFirstAndLastDayOfLastYearMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.YEAR, -1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
Date firstDayOfLastYearMonth = calendar.getTime();

calendar.add(Calendar.MONTH, 1);
calendar.add(Calendar.DAY_OF_MONTH, -1);
Date lastDayOfLastYearMonth = calendar.getTime();

return new Date[]{firstDayOfLastYearMonth, lastDayOfLastYearMonth};
}

// 方法3:返回當年的第一天和最后一天的日期
public static Date[] getFirstAndLastDayOfYear(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_YEAR, 1);
Date firstDayOfYear = calendar.getTime();

calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMaximum(Calendar.DAY_OF_YEAR));
Date lastDayOfYear = calendar.getTime();

return new Date[]{firstDayOfYear, lastDayOfYear};
}

// 方法4:返回去年的第一天和最后一天的日期
public static Date[] getFirstAndLastDayOfLastYear(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.YEAR, -1);
calendar.set(Calendar.DAY_OF_YEAR, 1);
Date firstDayOfLastYear = calendar.getTime();

calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMaximum(Calendar.DAY_OF_YEAR));
Date lastDayOfLastYear = calendar.getTime();

return new Date[]{firstDayOfLastYear, lastDayOfLastYear};
}

// 主函數用于自測
public static void main(String[] args) {
Date today = new Date();

Date[] monthDates = getFirstAndLastDayOfMonth(today);
System.out.println("當月的第一天: " + monthDates[0]);
System.out.println("當月的最后一天: " + monthDates[1]);

Date[] lastYearMonthDates = getFirstAndLastDayOfLastYearMonth(today);
System.out.println("去年當月的第一天: " + lastYearMonthDates[0]);
System.out.println("去年當月的最后一天: " + lastYearMonthDates[1]);

Date[] yearDates = getFirstAndLastDayOfYear(today);
System.out.println("當年的第一天: " + yearDates[0]);
System.out.println("當年的最后一天: " + yearDates[1]);

Date[] lastYearDates = getFirstAndLastDayOfLastYear(today);
System.out.println("去年的第一天: " + lastYearDates[0]);
System.out.println("去年的最后一天: " + lastYearDates[1]);
}
}

運行結果日期正確,但加上了運行時的時分秒,有點畫蛇添足。

當月的第一天: Thu Feb 01 20:58:37 CST 2024
當月的最后一天: Thu Feb 29 20:58:37 CST 2024
去年當月的第一天: Wed Feb 01 20:58:37 CST 2023
去年當月的最后一天: Tue Feb 28 20:58:37 CST 2023
當年的第一天: Mon Jan 01 20:58:37 CST 2024
當年的最后一天: Tue Dec 31 20:58:37 CST 2024
去年的第一天: Sun Jan 01 20:58:37 CST 2023
去年的最后一天: Sun Dec 31 20:58:37 CST 2023

測評分析結果:加分項:編譯正確;運行結果正確;方法命名比較好;提供了中文注釋;減分項:沒有代碼復用;結果加上了運行時的時分秒,有點畫蛇添足;評分:85分。

2、測評二:報表數據填充代碼生成

測評二也是來源于實際工作中的一個需求場景。報表數據的填充補全,入參是只有部分日期的當月報表數據,需要補充當月其它日期的數據記錄,輸出完整的當月數據記錄。

對應的提示詞如下:

有一個對象列表,List<TendencyChartVO>,TendencyChartVO對象有兩個字段:dt,name, 其中有一個dt字段,為日期類型。name為String類型。
對象列表里可能只有當月其中幾天的數據。幫我寫一個函數,填充當月剩余的日期數據,只填充dt字段值就可以,填充好以后對List<TendencyChartVO>按日期排序。同時提供main函數進行自測。

1)DeepSeek-Coder-33B-Instruct

生成的代碼:

package ai.deepseek;

import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public class TendencyChartVO {
private Date dt;
private String name;

public TendencyChartVO(Date dt, String name) {
this.dt = dt;
this.name = name;
}

public Date getDt() {
return dt;
}

public String getName() {
return name;
}

@Override
public String toString() {
return "TendencyChartVO{" +
"dt=" + dt +
", name='" + name + '\'' +
'}';
}

public static List<TendencyChartVO> fillAndSort(List<TendencyChartVO> list) {
// 獲取當前日期
LocalDate currentDate = LocalDate.now();
// 獲取當前月份的第一天和最后一天
LocalDate startOfMonth = currentDate.withDayOfMonth(1);
LocalDate endOfMonth = YearMonth.from(currentDate).atEndOfMonth();

// 創建一個新的列表來存儲填充后的數據
List<TendencyChartVO> filledList = new ArrayList<>(list);

// 遍歷當月的每一天
for (LocalDate date = startOfMonth; !date.isAfter(endOfMonth); date = date.plusDays(1)) {
// 將LocalDate轉換為Date
Date dt = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
// 檢查是否在原始列表中存在
LocalDate finalDate = date;
if (list.stream().noneMatch(vo -> convertToLocalDate(vo.getDt()).equals(finalDate))) {
// 如果不存在,創建一個新的TendencyChartVO對象并添加到列表中
filledList.add(new TendencyChartVO(dt, ""));
}
}

// 對列表進行排序
filledList.sort(Comparator.comparing(vo -> convertToLocalDate(vo.getDt())));

return filledList;
}

private static LocalDate convertToLocalDate(Date date) {
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}

public static void main(String[] args) {
// 創建一個示例列表
List<TendencyChartVO> list = new ArrayList<>();
list.add(new TendencyChartVO(Date.from(LocalDate.now().minusDays(5).atStartOfDay(ZoneId.systemDefault()).toInstant()), "Test1"));
list.add(new TendencyChartVO(Date.from(LocalDate.now().minusDays(2).atStartOfDay(ZoneId.systemDefault()).toInstant()), "Test2"));

// 填充并排序列表
List<TendencyChartVO> filledList = fillAndSort(list);

// 打印結果
filledList.forEach(System.out::println);
}
}

運行結果不正確,需要把minusDays改成plusDays后正確。

TendencyChartVO{dt=Mon Jan 29 00:00:00 CST 2024, name='Test1'}
TendencyChartVO{dt=Thu Feb 01 00:00:00 CST 2024, name='Test2'}
TendencyChartVO{dt=Fri Feb 02 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Sat Feb 03 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Sun Feb 04 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Mon Feb 05 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Tue Feb 06 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Wed Feb 07 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Thu Feb 08 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Fri Feb 09 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Sat Feb 10 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Sun Feb 11 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Mon Feb 12 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Tue Feb 13 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Wed Feb 14 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Thu Feb 15 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Fri Feb 16 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Sat Feb 17 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Sun Feb 18 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Mon Feb 19 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Tue Feb 20 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Wed Feb 21 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Thu Feb 22 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Fri Feb 23 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Sat Feb 24 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Sun Feb 25 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Mon Feb 26 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Tue Feb 27 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Wed Feb 28 00:00:00 CST 2024, name=''}
TendencyChartVO{dt=Thu Feb 29 00:00:00 CST 2024, name=''}

測評分析結果:

加分項:提供了比較清晰的中文注釋;

減分項:編譯有一處錯誤,51行的date需要改成final類型;運行結果不正確,需要把70-71行的minusDays方法改成plusDays才正確;方法內直接用了當前日期,可擴展性不好;評分:50分。
2)CodeLlama-70B-Instruct

生成的代碼:

package ai.codellama70b;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TendencyChartVO {
private String dt;
private String name;

public TendencyChartVO(String dt, String name) {
this.dt = dt;
this.name = name;
}

public String getDt() {
return dt;
}

public void setDt(String dt) {
this.dt = dt;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public static void main(String[] args) {
List<TendencyChartVO> list = new ArrayList<>();
list.add(new TendencyChartVO("2021-01-01", "name1"));
list.add(new TendencyChartVO("2021-01-03", "name2"));
list.add(new TendencyChartVO("2021-01-05", "name3"));
list.add(new TendencyChartVO("2021-01-07", "name4"));
list.add(new TendencyChartVO("2021-01-09", "name5"));
list.add(new TendencyChartVO("2021-01-11", "name6"));
list.add(new TendencyChartVO("2021-01-13", "name7"));
list.add(new TendencyChartVO("2021-01-15", "name8"));
list.add(new TendencyChartVO("2021-01-17", "name9"));
list.add(new TendencyChartVO("2021-01-19", "name10"));
list.add(new TendencyChartVO("2021-01-21", "name11"));
list.add(new TendencyChartVO("2021-01-23", "name12"));
list.add(new TendencyChartVO("2021-01-25", "name13"));
list.add(new TendencyChartVO("2021-01-27", "name14"));
list.add(new TendencyChartVO("2021-01-29", "name15"));
list.add(new TendencyChartVO("2021-01-31", "name16"));

fillMissingDates(list);

System.out.println("List after filling missing dates:");
for (TendencyChartVO vo : list) {
System.out.println(vo.getDt() + " " + vo.getName());
}
}

private static void fillMissingDates(List<TendencyChartVO> list) {
LocalDate startDate = LocalDate.parse(list.get(0).getDt(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate endDate = LocalDate.parse(list.get(list.size() - 1).getDt(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));

for (LocalDate date = startDate; date.isBefore(endDate.plusDays(1)); date = date.plusDays(1)) {
boolean found = false;
for (TendencyChartVO vo : list) {
if (date.equals(LocalDate.parse(vo.getDt(), DateTimeFormatter.ofPattern("yyyy-MM-dd")))) {
found = true;
break;
}
}
if (!found) {
list.add(new TendencyChartVO(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), null));
}
}

Collections.sort(list, Comparator.comparing(TendencyChartVO::getDt));
}
}

運行結果正確。

List after filling missing dates:
2021-01-01 name1
2021-01-02 null
2021-01-03 name2
2021-01-04 null
2021-01-05 name3
2021-01-06 null
2021-01-07 name4
2021-01-08 null
2021-01-09 name5
2021-01-10 null
2021-01-11 name6
2021-01-12 null
2021-01-13 name7
2021-01-14 null
2021-01-15 name8
2021-01-16 null
2021-01-17 name9
2021-01-18 null
2021-01-19 name10
2021-01-20 null
2021-01-21 name11
2021-01-22 null
2021-01-23 name12
2021-01-24 null
2021-01-25 name13
2021-01-26 null
2021-01-27 name14
2021-01-28 null
2021-01-29 name15
2021-01-30 null
2021-01-31 name16

測評分析結果:

加分項:編譯正確;運行結果正確;方法命名比較好;

減分項:代碼不夠簡潔;沒有注釋;評分:80分。

3)GLM-4

生成的代碼:

package ai.glm4;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class TendencyChartFiller {

static class TendencyChartVO {
Date dt;
String name;

public TendencyChartVO(Date dt, String name) {
this.dt = dt;
this.name = name;
}

@Override
public String toString() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return "TendencyChartVO{" +
"dt=" + sdf.format(dt) +
", name='" + name + '\'' +
'}';
}
}

public static void fillMissingDates(List<TendencyChartVO> list) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(list.get(0).dt);
int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

for (int i = 1; i <= daysInMonth; i++) {
Date currentDate = strToDate(sdf.format(calendar.getTime()));
boolean found = list.stream().anyMatch(vo -> sdf.format(vo.dt).equals(sdf.format(currentDate)));
if (!found) {
list.add(new TendencyChartVO(currentDate, ""));
}
calendar.add(Calendar.DAY_OF_MONTH, 1);
}

list.sort((o1, o2) -> o1.dt.compareTo(o2.dt));
}

public static Date strToDate(String str) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

public static void main(String[] args) {
List<TendencyChartVO> list = new ArrayList<>();
list.add(new TendencyChartVO(strToDate("2024-02-01"), "name1"));
list.add(new TendencyChartVO(strToDate("2024-02-03"), "name2"));
list.add(new TendencyChartVO(strToDate("2024-02-05"), "name3"));

fillMissingDates(list);

for (TendencyChartVO vo : list) {
System.out.println(vo);
}
}
}

運行結果正確。

TendencyChartVO{dt=2024-02-01, name='name1'}
TendencyChartVO{dt=2024-02-02, name=''}
TendencyChartVO{dt=2024-02-03, name='name2'}
TendencyChartVO{dt=2024-02-04, name=''}
TendencyChartVO{dt=2024-02-05, name='name3'}
TendencyChartVO{dt=2024-02-06, name=''}
TendencyChartVO{dt=2024-02-07, name=''}
TendencyChartVO{dt=2024-02-08, name=''}
TendencyChartVO{dt=2024-02-09, name=''}
TendencyChartVO{dt=2024-02-10, name=''}
TendencyChartVO{dt=2024-02-11, name=''}
TendencyChartVO{dt=2024-02-12, name=''}
TendencyChartVO{dt=2024-02-13, name=''}
TendencyChartVO{dt=2024-02-14, name=''}
TendencyChartVO{dt=2024-02-15, name=''}
TendencyChartVO{dt=2024-02-16, name=''}
TendencyChartVO{dt=2024-02-17, name=''}
TendencyChartVO{dt=2024-02-18, name=''}
TendencyChartVO{dt=2024-02-19, name=''}
TendencyChartVO{dt=2024-02-20, name=''}
TendencyChartVO{dt=2024-02-21, name=''}
TendencyChartVO{dt=2024-02-22, name=''}
TendencyChartVO{dt=2024-02-23, name=''}
TendencyChartVO{dt=2024-02-24, name=''}
TendencyChartVO{dt=2024-02-25, name=''}
TendencyChartVO{dt=2024-02-26, name=''}
TendencyChartVO{dt=2024-02-27, name=''}
TendencyChartVO{dt=2024-02-28, name=''}
TendencyChartVO{dt=2024-02-29, name=''}

測評分析結果:

加分項:編譯正確;運行結果正確;類和方法命名比較好;

減分項:沒有注釋;

評分:85分。

4)GPT-3.5

生成的代碼:

package ai.gpt35;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public class TendencyChartFiller {

public static void main(String[] args) {
// Sample data with incomplete dates
List<TendencyChartVO> tendencyChartList = new ArrayList<>();
tendencyChartList.add(new TendencyChartVO(parseDate("2024-02-01"), "Data1"));
tendencyChartList.add(new TendencyChartVO(parseDate("2024-02-03"), "Data2"));

// Fill and sort
fillAndSortTendencyChartList(tendencyChartList);

// Print result
for (TendencyChartVO vo : tendencyChartList) {
System.out.println("Date: " + formatDate(vo.getDt()) + ", Name: " + vo.getName());
}
}

public static void fillAndSortTendencyChartList(List<TendencyChartVO> list) {
// Get the first and last day of the current month
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH, 1);
Date firstDay = calendar.getTime();

calendar.add(Calendar.MONTH, 1);
calendar.add(Calendar.DAY_OF_MONTH, -1);
Date lastDay = calendar.getTime();

// Fill missing dates in the list
while (firstDay.before(lastDay)) {
boolean containsDate = false;
for (TendencyChartVO vo : list) {
if (vo.getDt().equals(firstDay)) {
containsDate = true;
break;
}
}

if (!containsDate) {
list.add(new TendencyChartVO(new Date(firstDay.getTime()), null));
}

calendar.setTime(firstDay);
calendar.add(Calendar.DAY_OF_MONTH, 1);
firstDay = calendar.getTime();
}

// Sort the list by date
Collections.sort(list, Comparator.comparing(TendencyChartVO::getDt));
}

public static Date parseDate(String dateString) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.parse(dateString);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

public static String formatDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
}

class TendencyChartVO {
private Date dt;
private String name;

public TendencyChartVO(Date dt, String name) {
this.dt = dt;
this.name = name;
}

public Date getDt() {
return dt;
}

public String getName() {
return name;
}
}

運行結果運行結果不正確,2024-02-01多了一條,2024-2-29少了一條。

Date: 2024-02-01, Name: Data1
Date: 2024-02-01, Name: null
Date: 2024-02-02, Name: null
Date: 2024-02-03, Name: Data2
Date: 2024-02-03, Name: null
Date: 2024-02-04, Name: null
Date: 2024-02-05, Name: null
Date: 2024-02-06, Name: null
Date: 2024-02-07, Name: null
Date: 2024-02-08, Name: null
Date: 2024-02-09, Name: null
Date: 2024-02-10, Name: null
Date: 2024-02-11, Name: null
Date: 2024-02-12, Name: null
Date: 2024-02-13, Name: null
Date: 2024-02-14, Name: null
Date: 2024-02-15, Name: null
Date: 2024-02-16, Name: null
Date: 2024-02-17, Name: null
Date: 2024-02-18, Name: null
Date: 2024-02-19, Name: null
Date: 2024-02-20, Name: null
Date: 2024-02-21, Name: null
Date: 2024-02-22, Name: null
Date: 2024-02-23, Name: null
Date: 2024-02-24, Name: null
Date: 2024-02-25, Name: null
Date: 2024-02-26, Name: null
Date: 2024-02-27, Name: null
Date: 2024-02-28, Name: null

測評分析結果:

加分項:編譯正確;有英文注釋;

減分項:運行結果不正確,2024-02-01多了一條,2024-2-29少了一條;代碼不夠清晰簡潔;評分:50分。

5)GPT-4-0613

生成的代碼:

package ai.gpt4;

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

class TendencyChartVO {
LocalDate dt;
String name;

public TendencyChartVO(LocalDate dt, String name) {
this.dt = dt;
this.name = name;
}

// Getter 和 Setter 方法省略...

@Override
public String toString() {
return "TendencyChartVO{" + "dt=" + dt + ", name='" + name + '\'' + '}';
}

public static void main(String[] args) {
List<TendencyChartVO> list = new ArrayList<>();
list.add(new TendencyChartVO(LocalDate.of(2024, 2, 5), "數據1"));
list.add(new TendencyChartVO(LocalDate.of(2024, 2, 15), "數據2"));

List<TendencyChartVO> filledList = fillDatesAndSort(list, 2024, 2);
for (TendencyChartVO item : filledList) {
System.out.println(item);
}
}

private static List<TendencyChartVO> fillDatesAndSort(List<TendencyChartVO> list, int year, int month) {
Set<LocalDate> existingDates = new HashSet<>();
for (TendencyChartVO item : list) {
existingDates.add(item.dt);
}

LocalDate firstDayOfMonth = LocalDate.of(year, month, 1);
LocalDate lastDayOfMonth = firstDayOfMonth.with(TemporalAdjusters.lastDayOfMonth());

for (LocalDate date = firstDayOfMonth; !date.isAfter(lastDayOfMonth); date = date.plusDays(1)) {
if (!existingDates.contains(date)) {
list.add(new TendencyChartVO(date, null));
}
}

Collections.sort(list, new Comparator<TendencyChartVO>() {
@Override
public int compare(TendencyChartVO o1, TendencyChartVO o2) {
return o1.dt.compareTo(o2.dt);
}
});

return list;
}
}

運行結果正確。

TendencyChartVO{dt=2024-02-01, name='null'}
TendencyChartVO{dt=2024-02-02, name='null'}
TendencyChartVO{dt=2024-02-03, name='null'}
TendencyChartVO{dt=2024-02-04, name='null'}
TendencyChartVO{dt=2024-02-05, name='數據1'}
TendencyChartVO{dt=2024-02-06, name='null'}
TendencyChartVO{dt=2024-02-07, name='null'}
TendencyChartVO{dt=2024-02-08, name='null'}
TendencyChartVO{dt=2024-02-09, name='null'}
TendencyChartVO{dt=2024-02-10, name='null'}
TendencyChartVO{dt=2024-02-11, name='null'}
TendencyChartVO{dt=2024-02-12, name='null'}
TendencyChartVO{dt=2024-02-13, name='null'}
TendencyChartVO{dt=2024-02-14, name='null'}
TendencyChartVO{dt=2024-02-15, name='數據2'}
TendencyChartVO{dt=2024-02-16, name='null'}
TendencyChartVO{dt=2024-02-17, name='null'}
TendencyChartVO{dt=2024-02-18, name='null'}
TendencyChartVO{dt=2024-02-19, name='null'}
TendencyChartVO{dt=2024-02-20, name='null'}
TendencyChartVO{dt=2024-02-21, name='null'}
TendencyChartVO{dt=2024-02-22, name='null'}
TendencyChartVO{dt=2024-02-23, name='null'}
TendencyChartVO{dt=2024-02-24, name='null'}
TendencyChartVO{dt=2024-02-25, name='null'}
TendencyChartVO{dt=2024-02-26, name='null'}
TendencyChartVO{dt=2024-02-27, name='null'}
TendencyChartVO{dt=2024-02-28, name='null'}
TendencyChartVO{dt=2024-02-29, name='null'}

測評分析結果:加分項:編譯正確;運行結果正確;代碼清晰;方法命名比較好;減分項:沒有注釋;方法的第二、三入參有點多余;評分:85分。

3、測評三:代碼補全

測評三是需要實現一個字符串數據處理方法,根據注釋里的實現步驟,進行代碼補全。

提示詞如下:

你是一個優秀的java開發工程師,致力于寫出高質量的代碼。現在給你一個代碼類,根據代碼骨架和注釋補全生成完整的代碼。
要求:
1.保證代碼的準確性,可讀性,可維護性;
2.使用子函數封裝,每個方法盡量不超過50行;
3.在駝峰格式轉成下劃線格式的方法中,打印出轉成下劃線格式后的那個值;
4.包括main函數,可以進行自測;

public class Transformer {

public String transform(String source) {
//1.對source實現對駝峰格式轉成下劃線格式的功能

//2.再進行MD5摘要

//3.最后加上當前時間戳,以$符號連接。

}

}

1)DeepSeek-Coder-33B-Instruct
生成的代碼:

package ai.deepseek;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.time.Instant;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Transformer {

public String transform(String source) {
// 1. 對source實現對駝峰格式轉成下劃線格式的功能
String underlineFormat = camelToUnderline(source);
System.out.println("Underline format: " + underlineFormat);

// 2. 再進行MD5摘要
String md5Digest = DigestUtils.md5Hex(underlineFormat);

// 3. 最后加上當前時間戳,以$符號連接
long timestamp = Instant.now().toEpochMilli();
return md5Digest + "$" + timestamp;
}

private String camelToUnderline(String source) {
// 使用正則表達式匹配駝峰格式,并替換為下劃線格式
Matcher matcher = Pattern.compile("[A-Z]").matcher(source);
StringBuffer sb = new StringBuffer(source);
if (matcher.find()) {
sb = new StringBuffer();
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
matcher.appendTail(sb);
} else {
return source;
}
return camelToUnderline(sb.toString());
}

public static void main(String[] args) {
Transformer transformer = new Transformer();
String source = "camelCaseExample";
String transformed = transformer.transform(source);
System.out.println("Transformed: " + transformed);
}
}

運行結果正確。

Underline format: camel_case_example
Transformed: fd7cbc4baf7cc4d892d5475c85308d4d$1707009362279

測評分析結果:

加分項:編譯正確;運行結果正確;代碼清晰,會使用第三方工具類簡化代碼;有中文注釋;

減分項:沒有考慮首字母大寫時的特殊處理情況;評分:85分。
2)CodeLlama-70B-Instruct

生成的代碼:

package ai.codellama70b;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Transformer {

public String transform(String source) {
String camelCase = camelToUnderline(source);
String md5 = md5(camelCase);
String timestamp = timestamp();
return md5 + "$" + timestamp;
}

private String camelToUnderline(String source) {
// 將駝峰格式轉換為下劃線格式
System.out.println(source.replaceAll("([A-Z])", "_$1").toLowerCase());
return source.replaceAll("([A-Z])", "_$1").toLowerCase();
}

private String md5(String source) {
// 對字符串進行MD5摘要
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(source.getBytes());
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
result.append("0");
}
result.append(hex);
}
return result.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}

private String timestamp() {
// 獲取當前時間戳
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
return sdf.format(new Date());
}

public static void main(String[] args) {
Transformer transformer = new Transformer();
String source = "HelloWorld";
String result = transformer.transform(source);
System.out.println(result);
}

}

運行結果不正確。

_hello_world
f36965787cd64350c4960ebdc24c4ad8$20240204092431

測評分析結果:

加分項:編譯正確;有中文注釋;

減分項:沒有考慮首字母大寫時的特殊處理情況,導致運行結果不正確;駝峰轉下劃線格式重復調用了兩次;評分:60分。
3)GLM-4
生成的代碼:

package ai.glm4;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Transformer {

public String transform(String source) {
String underscored = camelToUnderscore(source);
String md5 = getMD5(underscored);
String timestamp = getCurrentTimestamp();
return md5 + "$" + timestamp;
}

private String camelToUnderscore(String source) {
StringBuilder result = new StringBuilder();
for (char c : source.toCharArray()) {
if (Character.isUpperCase(c)) {
result.append("_").append(Character.toLowerCase(c));
} else {
result.append(c);
}
}
System.out.println("Underscored value: " + result.toString());
return result.toString();
}

private String getMD5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(input.getBytes());
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}

private String getCurrentTimestamp() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}

public static void main(String[] args) {
Transformer transformer = new Transformer();
String result = transformer.transform("HelloWorld");
System.out.println("Transformed result: " + result);
}
}

運行結果不正確。

Underscored value: _hello_world
Transformed result: f36965787cd64350c4960ebdc24c4ad8$2024-02-04 19:47:36

測評分析結果:

加分項:編譯正確;

減分項:沒有考慮首字母大寫時的特殊處理情況,導致運行結果不正確;沒有注釋;評分:60分。
4)GPT-3.5
生成的代碼:

package ai.gpt35;

import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Transformer {

public static void main(String[] args) {
Transformer transformer = new Transformer();

// Test case: transform a sample source string
String source = "sampleSourceString";
String result = transformer.transform(source);
System.out.println("Transformed Result: " + result);
}

public String transform(String source) {
// 1. Convert camel case to underscore format
String underscoredString = convertCamelToUnderscore(source);
System.out.println("Underscored Format: " + underscoredString);

// 2. Calculate MD5 digest
String md5Digest = calculateMD5(underscoredString);

// 3. Append current timestamp with "$" symbol
String result = md5Digest + "$" + getCurrentTimestamp();

return result;
}

private String convertCamelToUnderscore(String camelCase) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < camelCase.length(); i++) {
char currentChar = camelCase.charAt(i);
if (Character.isUpperCase(currentChar) && i > 0) {
result.append("_").append(Character.toLowerCase(currentChar));
} else {
result.append(currentChar);
}
}
return result.toString();
}

private String calculateMD5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(input.getBytes());
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
} catch (Exception e) {
e.printStackTrace();
return "";
}
}

private String getCurrentTimestamp() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
return sdf.format(new Date());
}
}

運行結果正確。

Underscored Format: sample_source_string
Transformed Result: 091513cdffb0896114910a2a3b4e1c22$20240204195225

測評分析結果:

加分項:編譯正確;運行結果正確;代碼清晰;有英文注釋;

減分項:沒有考慮首字母大寫時的特殊處理情況;評分:80分。
5)GPT-4-0613
生成的代碼:

package ai.gpt4;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Transformer {

public static void main(String[] args) {
Transformer transformer = new Transformer();
String result = transformer.transform("SampleInputStringForTesting");
System.out.println(result);
}

public String transform(String source) {
String underscored = camelToUnderscore(source);
String md5Digest = md5(underscored);
return md5Digest + "$" + System.currentTimeMillis();
}

private String camelToUnderscore(String source) {
if (source == null) {
return null;
}
StringBuilder builder = new StringBuilder();
for (char c : source.toCharArray()) {
if (Character.isUpperCase(c)) {
if (builder.length() > 0) {
builder.append('_');
}
builder.append(Character.toLowerCase(c));
} else {
builder.append(c);
}
}
String underscored = builder.toString();
System.out.println(underscored); // 打印轉換后的字符串
return underscored;
}

private String md5(String source) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(source.getBytes());
return bytesToHex(digest);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}

private String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}

}

運行結果正確。

sample_input_string_for_testing
4fbf32fbec3b2adbed3d52e15090a2d7$1707047846034

測評分析結果:

加分項:編譯正確;運行結果正確;代碼清晰;考慮首字母大寫時的特殊處理情況;

減分項:沒有注釋;

評分:90分。

4、測評四:代碼優化

測評四是一個數組內數據處理的算法優化。在數字數組內查找是否有兩個數的和等于給定的值,原方法的算法復雜度是O(n^2),需要通過優化來降低算法復雜度。

提示詞如下:

你是一個優秀的java開發工程師,致力于寫出高質量的代碼。現在給你一個類,對這個類進行優化,給出優化后的完整代碼。
要求:
1.保證代碼的準確性,可讀性,可維護性;
2.代碼盡量簡潔,能使用lambda表達式最好;
3.保證語法正確性;
4.包括main函數,可以進行自測。

public class DoubleSumToValue {

public static boolean doubleSumToValue(int[] listOfInts, int value) {
if (listOfInts.length < 2) {
return false;
} else {
for (int i = 0; i < listOfInts.length - 1; i++) {
for (int j = i + 1; j < listOfInts.length; j++) {
if (listOfInts[i] + listOfInts[j] == value) {
return true;
}
}
}
return false;
}
}

public static void main(String[] args) {
int[] listOfInts = {1, 2, 3, 4, 5};
int value = 8;
boolean result = doubleSumToValue(listOfInts, value);
System.out.println("Result: " + result);
}
}

1)DeepSeek-Coder-33B-Instruct
生成的代碼:

package ai.deepseek;

import java.util.HashSet;
import java.util.Set;

public class DoubleSumToValue {

public static boolean doubleSumToValue(int[] listOfInts, int value) {
if (listOfInts.length < 2) {
return false;
}

Set<Integer> complements = new HashSet<>();
for (int num : listOfInts) {
if (complements.contains(num)) {
return true;
}
complements.add(value - num);
}

return false;
}

public static void main(String[] args) {
int[] listOfInts = {1, 2, 3, 4, 5};
int value = 8;
boolean result = doubleSumToValue(listOfInts, value);
System.out.println("Result: " + result);
}
}

運行結果正確。

Result: true

測評分析結果:

加分項:編譯正確;運行結果正確;算法復雜度優化為O(n);集合命名為complements,能表達相減的余數的含義;

減分項:沒有注釋;

評分:85分。

2)CodeLlama-70B-Instruct

生成的代碼:

package ai.codellama70b;

import java.util.HashSet;
import java.util.Set;

public class DoubleSumToValue {

public static boolean doubleSumToValue(int[] listOfInts, int value) {
if (listOfInts.length < 2) {
return false;
}
Set<Integer> set = new HashSet<>();
for (int num : listOfInts) {
if (set.contains(value - num)) {
return true;
}
set.add(num);
}

return false;

}
public static void main(String[] args) {
int[] listOfInts = {1, 2, 3, 4, 5};
int value = 8;
boolean result = doubleSumToValue(listOfInts, value);
System.out.println("Result: " + result);
}
}

運行結果正確。


Result: true

測評分析結果:

加分項:編譯正確;運行結果正確;算法復雜度優化為O(n);

減分項:集合直接命名為set,沒有表達出語義;沒有注釋;

評分:80分。

3)GLM-4
生成的代碼:

package ai.glm4;

import java.util.HashSet;
import java.util.Set;

public class DoubleSumToValue {

public static boolean doubleSumToValue(int[] listOfInts, int value) {
if (listOfInts.length < 2) {
return false;
}

Set<Integer> seen = new HashSet<>();
for (int num : listOfInts) {
if (seen.contains(value - num)) {
return true;
}
seen.add(num);
}
return false;
}

public static void main(String[] args) {
int[] listOfInts = {1, 2, 3, 4, 5};
int value = 8;
boolean result = doubleSumToValue(listOfInts, value);
System.out.println("Result: " + result);
}
}

運行結果正確。

Result: true

測評分析結果:

加分項:編譯正確;運行結果正確;算法復雜度優化為O(n);

減分項:集合命名為seen,看見過的,沒有把復數表示出來;沒有注釋;

評分:80分。 

4)GPT-3.5
生成的代碼:

package ai.gpt35;

import java.util.HashSet;
import java.util.Set;

public class DoubleSumToValue {

public static boolean doubleSumToValue(int[] listOfInts, int value) {
if (listOfInts.length < 2) {
return false;
}

Set<Integer> set = new HashSet<>();

for (int num : listOfInts) {
int complement = value - num;
if (set.contains(complement)) {
return true;
}
set.add(num);
}

return false;
}

public static void main(String[] args) {
int[] listOfInts = {1, 2, 3, 4, 5};
int value = 8;
boolean result = doubleSumToValue(listOfInts, value);
System.out.println("Result: " + result);
}
}

運行結果正確。

Result: true

測評分析結果:

加分項:編譯正確;運行結果正確;算法復雜度優化為O(n);集合命名為set,里面用到了complement,能表達相減的余數的含義。;

減分項:沒有注釋;評分:85分。 

5)GPT-4-0613
生成的代碼:

package ai.gpt4;

import java.util.HashSet;

/**
* Utility class to check if any two distinct numbers in an array sum up to a specific value.
*/
public class DoubleSumToValue {

/**
* Checks if any two distinct numbers in the array sum up to the given value.
* @param numbers Array of integers to check.
* @param targetValue The target sum value.
* @return true if two distinct numbers sum up to targetValue, false otherwise.
*/
public static boolean hasPairWithSum(int[] numbers, int targetValue) {
HashSet<Integer> seenNumbers = new HashSet<>();
for (int number : numbers) {
if (seenNumbers.contains(targetValue - number)) {
return true;
}
seenNumbers.add(number);
}
return false;
}

public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
int targetValue = 8;
boolean result = hasPairWithSum(numbers, targetValue);
System.out.println("Result: " + result);
}
}

運行結果正確。

Result: true

測評分析結果:

加分項:編譯正確;運行結果正確;算法復雜度優化為O(n);集合命名為seenNumbers,表示看見過的數字,另外對方法進行了重命名;增加了英文注釋;

減分項:沒有中文注釋;

評分:90分。 

5、測評五:代碼糾錯

日常開發中經常會碰到,需要尋找或者檢查一段代碼中的是否有bug的情況。測評五是比對兩個同類型對象是否相同的代碼,其中”StringUtils.isEmpty(that.storeId)?null:this.storeId)”這句存在bug。
提示詞如下:

幫我查找這段代碼中的bug,給出完整的類并包括main函數,可以進行自測對象為空的情況:
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SkuKey)) {
return false;
}
SkuKey that = (SkuKey) o;
return new EqualsBuilder()
.append(skuId, that.skuId)
.append(StringUtils.isEmpty(storeId)?null:storeId, StringUtils.isEmpty(that.storeId)?null:this.storeId)
.isEquals();
}

1)DeepSeek-Coder-33B-Instruct
生成的代碼:

package ai.deepseek;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.StringUtils;

public class SkuKey {
private String skuId;
private String storeId;

public SkuKey(String skuId, String storeId) {
this.skuId = skuId;
this.storeId = storeId;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SkuKey)) {
return false;
}
SkuKey that = (SkuKey) o;
return new EqualsBuilder()
.append(skuId, that.skuId)
.append(normalizeStoreId(storeId), normalizeStoreId(that.storeId))
.isEquals();
}

private String normalizeStoreId(String storeId) {
return StringUtils.isEmpty(storeId) ? null : storeId;
}

public static void main(String[] args) {
// 測試對象為空的情況
SkuKey key1 = new SkuKey("123", "store1");
SkuKey key2 = new SkuKey("123", null);
SkuKey key3 = new SkuKey(null, "store1");
SkuKey key4 = new SkuKey(null, null);

System.out.println("key1 equals key2: " + key1.equals(key2)); // Expected: true
System.out.println("key1 equals key3: " + key1.equals(key3)); // Expected: false
System.out.println("key2 equals key3: " + key2.equals(key3)); // Expected: false
System.out.println("key1 equals key4: " + key1.equals(key4)); // Expected: false
System.out.println("key2 equals key4: " + key2.equals(key4)); // Expected: false
System.out.println("key3 equals key4: " + key3.equals(key4)); // Expected: true
}
}

運行結果按照main方法自測用例,注釋的預期值,有兩個不符合預期。

key1 equals key2: false
key1 equals key3: false
key2 equals key3: false
key1 equals key4: false
key2 equals key4: false
key3 equals key4: false

測評分析結果:

加分項:編譯正確;能找到并修復代碼中的bug;能提煉出方法進行復用;

減分項:按照main方法自測用例,注釋的預期值,有兩個不符合預期;

評分:80分。
2)CodeLlama-70B-Instruct

生成的代碼:

package ai.codellama70b;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.StringUtils;

public class SkuKey {
private String skuId;
private String storeId;

public SkuKey(String skuId, String storeId) {
this.skuId = skuId;
this.storeId = storeId;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SkuKey)) {
return false;
}
SkuKey that = (SkuKey) o;
return new EqualsBuilder()
.append(skuId, that.skuId)
.append(StringUtils.isEmpty(storeId) ? null : storeId, StringUtils.isEmpty(that.storeId) ? null : that.storeId)
.isEquals();
}

public static void main(String[] args) {
SkuKey skuKey1 = new SkuKey("123", "");
SkuKey skuKey2 = new SkuKey("123", null);
System.out.println(skuKey1.equals(skuKey2));
}
}

測評分析結果:

加分項:編譯正確;

減分項:生成的代碼不穩定,試了幾次,有時候能找到bug,有時找不到bug;

評分:50分。

3)GLM-4
生成的代碼:

package ai.glm4;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

public class StarSkuKey {
private String skuId;
private String storeId;

public StarSkuKey(String skuId, String storeId) {
this.skuId = skuId;
this.storeId = storeId;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof StarSkuKey)) {
return false;
}
StarSkuKey that = (StarSkuKey) o;
return new EqualsBuilder()
.append(skuId, that.skuId)
.append(storeId, that.storeId)
.isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(skuId)
.append(storeId)
.toHashCode();
}

public static void main(String[] args) {
StarSkuKey key1 = new StarSkuKey("123", "456");
StarSkuKey key2 = new StarSkuKey("123", "456");
StarSkuKey key3 = new StarSkuKey("123", null);
StarSkuKey key4 = new StarSkuKey(null, "456");
StarSkuKey key5 = new StarSkuKey(null, null);

System.out.println("key1 equals key2: " + key1.equals(key2)); // true
System.out.println("key1 equals key3: " + key1.equals(key3)); // false
System.out.println("key1 equals key4: " + key1.equals(key4)); // false
System.out.println("key1 equals key5: " + key1.equals(key5)); // false
System.out.println("key3 equals key5: " + key3.equals(key5)); // true
System.out.println("key4 equals key5: " + key4.equals(key5)); // false

// Test null object
System.out.println("key1 equals null: " + key1.equals(null)); // false
}
}

測評分析結果:

加分項:編譯正確;能找到并修復代碼中的bug;

減分項:修改了代碼,缺失了原來比對””和null含義相同的邏輯;自測預期結果和實際結果有不相符的情況;

評分:60分。 

4)GPT-3.5
生成的代碼:

package ai.gpt35;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.StringUtils;

public class SkuKey {

private String skuId;
private String storeId;

public SkuKey(String skuId, String storeId) {
this.skuId = skuId;
this.storeId = storeId;
}

// getters and setters

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SkuKey)) {
return false;
}
SkuKey that = (SkuKey) o;

return new EqualsBuilder()
.append(skuId, that.skuId)
.append(StringUtils.isEmpty(storeId) ? null : storeId, StringUtils.isEmpty(that.storeId) ? null : that.storeId)
.isEquals();
}

public static void main(String[] args) {
// Test case: objects with empty storeId
SkuKey key1 = new SkuKey("sku1", "");
SkuKey key2 = new SkuKey("sku1", "");

System.out.println("Objects are equal: " + key1.equals(key2));
}
}

測評分析結果:

加分項:編譯正確;能找到并修復代碼中的bug;

減分項:自測用例有點少;

評分:80分。 

5)GPT-4-0613
生成的代碼:

package ai.gpt4;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;

public class SkuKey {
private String skuId;
private String storeId;

// 構造函數
public SkuKey(String skuId, String storeId) {
this.skuId = skuId;
this.storeId = storeId;
}

// equals 方法
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SkuKey)) {
return false;
}
SkuKey that = (SkuKey) o;
return new EqualsBuilder()
.append(skuId, that.skuId)
.append(StringUtils.isEmpty(storeId) ? null : storeId, StringUtils.isEmpty(that.storeId) ? null : that.storeId)
.isEquals();
}

// hashCode 方法(如果重寫 equals,通常也需要重寫 hashCode)
@Override
public int hashCode() {
// hashCode 實現,可以使用 Objects.hashCode() 或者 HashCodeBuilder
// 這里僅為示例,實際情況可能需要更復雜的邏輯
return skuId.hashCode() + (storeId == null ? 0 : storeId.hashCode());
}

// main 方法,用于自測
public static void main(String[] args) {
SkuKey skuKey1 = new SkuKey("sku123", "store456");
SkuKey skuKey2 = new SkuKey("sku123", "store456");
SkuKey skuKey3 = new SkuKey("sku123", "");
SkuKey skuKey4 = new SkuKey("sku123", null);

System.out.println("skuKey1 equals skuKey2: " + skuKey1.equals(skuKey2)); // 應該輸出 true
System.out.println("skuKey1 equals skuKey3: " + skuKey1.equals(skuKey3)); // 應該輸出 false
System.out.println("skuKey1 equals skuKey4: " + skuKey1.equals(skuKey4)); // 應該輸出 false
System.out.println("skuKey3 equals skuKey4: " + skuKey3.equals(skuKey4)); // 應該輸出 true
}
}

測評分析結果:

加分項:編譯正確;能找到并修復代碼中的bug;自測用例比較全,能get到值為null和值為””要識別成相等的點;有中文注釋;

減分項:無;

評分:100分。 

6、測評六:單元測試

測評六是日常開發中必備的單元測試代碼生成。給定一個問題數據查詢引擎類,需要實現對應的單元測試代碼。
提示詞如下:

你是一個優秀的java開發工程師,致力于寫出高質量的單元測試代碼。現在給你一個類,幫我生成單元測試代碼,要求使用junit4,mockito3,盡量保證100%的代碼行覆蓋率,同時保證代碼的準確性,可讀性。

import com.demo.dao.mapper.ViewResultMapper;
import com.demo.model.ViewColumn;
import com.demo.model.ViewConfig;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service("problemDataViewQueryEngine")
public class ProblemDataViewQueryEngine implements DataViewQueryEngine{

@Autowired
private ViewResultMapper viewResultMapper;

@Override
public LinkedHashMap<String, List<Map<String, Object>>> queryViewData(List<ViewConfig> viewConfigModelList, Integer year, Integer quarter) {
int currentYear = 2023;
int currentQuarter = 1;
if (CollectionUtils.isEmpty(viewConfigModelList)) {
throw new IllegalArgumentException("Parameter viewConfigModelList is empty");
}
if (year == null) {
throw new IllegalArgumentException("Parameter year is empty");
}
if (quarter == null) {
throw new IllegalArgumentException("Parameter quarter is empty");
}
//存放返回值
LinkedHashMap<String, List<Map<String, Object>>> viewData = new LinkedHashMap<>();
for (ViewConfig viewConfig : viewConfigModelList) {
//sheet頁名稱
String sheetName = viewConfig.getSheet();
for (ViewColumn columnConfig : viewConfig.getColumns()) {
if (StringUtils.isEmpty(columnConfig.getSql())) {
continue;
}
if (year.equals(currentYear) && quarter.equals(currentQuarter)) {
columnConfig.setSql(columnConfig.getSql().replace("#{currentyear}", year.toString()));
columnConfig.setSql(columnConfig.getSql().replace("#{currentquarter}", quarter.toString()));
} else {
columnConfig.setSql(columnConfig.getSql().replace("#{year}", year.toString()));
columnConfig.setSql(columnConfig.getSql().replace("#{quarter}", quarter.toString()));
}
//查詢數據
List<Map<String, Object>> viewResultList = viewResultMapper.selectDataView(columnConfig.getSql());
viewData.put(sheetName, viewResultList);
}
}
return viewData;
}
}

1)DeepSeek-Coder-33B-Instruct
生成的單元測試如下。代碼編譯正確,生成了6個測試用例,行覆蓋率達到100%。

package ai.deepseek;

import ai.demo.dao.mapper.ViewResultMapper;
import ai.demo.model.ViewColumn;
import ai.demo.model.ViewConfig;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;

public class ProblemDataViewQueryEngineTestDeepseek {

@Mock
private ViewResultMapper viewResultMapper;

@InjectMocks
private ProblemDataViewQueryEngine problemDataViewQueryEngine;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}

@Test
public void testQueryViewData_withValidInput() {
// Arrange
List<ViewConfig> viewConfigModelList = new ArrayList<>();
ViewConfig viewConfig = new ViewConfig();
viewConfig.setSheet("Sheet1");
List<ViewColumn> columns = new ArrayList<>();
ViewColumn column = new ViewColumn();
column.setSql("SELECT * FROM table WHERE year = #{year} AND quarter = #{quarter}");
columns.add(column);
viewConfig.setColumns(columns);
viewConfigModelList.add(viewConfig);

List<Map<String, Object>> viewResultList = new ArrayList<>();
Map<String, Object> viewResult = new LinkedHashMap<>();
viewResult.put("column1", "value1");
viewResultList.add(viewResult);

when(viewResultMapper.selectDataView(anyString())).thenReturn(viewResultList);

// Act
LinkedHashMap<String, List<Map<String, Object>>> result = problemDataViewQueryEngine.queryViewData(viewConfigModelList, 2022, 1);

// Assert
assertEquals(1, result.size());
assertEquals(viewResultList, result.get("Sheet1"));
verify(viewResultMapper, times(1)).selectDataView(anyString());
}

@Test
public void testQueryViewData_withEmptyViewConfigModelList() {
// Arrange
List<ViewConfig> viewConfigModelList = new ArrayList<>();

// Act and Assert
assertThrows(IllegalArgumentException.class, () -> {
problemDataViewQueryEngine.queryViewData(viewConfigModelList, 2022, 1);
});
}

@Test
public void testQueryViewData_withNullYear() {
// Arrange
List<ViewConfig> viewConfigModelList = new ArrayList<>();
ViewConfig viewConfig = new ViewConfig();
viewConfig.setSheet("Sheet1");
viewConfigModelList.add(viewConfig);

// Act and Assert
assertThrows(IllegalArgumentException.class, () -> {
problemDataViewQueryEngine.queryViewData(viewConfigModelList, null, 1);
});
}

@Test
public void testQueryViewData_withNullQuarter() {
// Arrange
List<ViewConfig> viewConfigModelList = new ArrayList<>();
ViewConfig viewConfig = new ViewConfig();
viewConfig.setSheet("Sheet1");
viewConfigModelList.add(viewConfig);

// Act and Assert
assertThrows(IllegalArgumentException.class, () -> {
problemDataViewQueryEngine.queryViewData(viewConfigModelList, 2022, null);
});
}

@Test
public void testQueryViewData_withEmptySql() {
// Arrange
List<ViewConfig> viewConfigModelList = new ArrayList<>();
ViewConfig viewConfig = new ViewConfig();
viewConfig.setSheet("Sheet1");
List<ViewColumn> columns = new ArrayList<>();
ViewColumn column = new ViewColumn();
column.setSql("");
columns.add(column);
viewConfig.setColumns(columns);
viewConfigModelList.add(viewConfig);

// Act
LinkedHashMap<String, List<Map<String, Object>>> result = problemDataViewQueryEngine.queryViewData(viewConfigModelList, 2022, 1);

// Assert
assertEquals(0, result.size());
verify(viewResultMapper, never()).selectDataView(anyString());
}

@Test
public void testQueryViewData_withCurrentYearAndQuarter() {
// Arrange
List<ViewConfig> viewConfigModelList = new ArrayList<>();
ViewConfig viewConfig = new ViewConfig();
viewConfig.setSheet("Sheet1");
List<ViewColumn> columns = new ArrayList<>();
ViewColumn column = new ViewColumn();
column.setSql("SELECT * FROM table WHERE year = #{currentyear} AND quarter = #{currentquarter}");
columns.add(column);
viewConfig.setColumns(columns);
viewConfigModelList.add(viewConfig);

List<Map<String, Object>> viewResultList = new ArrayList<>();
Map<String, Object> viewResult = new LinkedHashMap<>();
viewResult.put("column1", "value1");
viewResultList.add(viewResult);

when(viewResultMapper.selectDataView(anyString())).thenReturn(viewResultList);

// Act
LinkedHashMap<String, List<Map<String, Object>>> result = problemDataViewQueryEngine.queryViewData(viewConfigModelList, 2023, 1);

// Assert
assertEquals(1, result.size());
assertEquals(viewResultList, result.get("Sheet1"));
verify(viewResultMapper, times(1)).selectDataView(anyString());
}
}

測評分析結果:

加分項:編譯正確;生成了6個測試用例,運行通過6個測試用例,行覆蓋率達到100%;

減分項:試第二次,行覆蓋率降到80%,不夠穩定;評分:90分。 

2)CodeLlama-70B-Instruct

生成的單元測試如下。代碼編譯正確,生成了1個測試用例,行覆蓋率76%。

package ai.codellama70b;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import ai.demo.dao.mapper.ViewResultMapper;
import ai.demo.model.ViewColumn;
import ai.demo.model.ViewConfig;

@RunWith(MockitoJUnitRunner.class)
public class ProblemDataViewQueryEngineTestCodeLlama70b {

@Mock
private ViewResultMapper viewResultMapper;

@InjectMocks
private ProblemDataViewQueryEngine problemDataViewQueryEngine;

@Test
public void testQueryViewData() {
// Arrange
List<ViewConfig> viewConfigModelList = new ArrayList<>();
ViewConfig viewConfig = new ViewConfig();
viewConfig.setSheet("Sheet1");
List<ViewColumn> columns = new ArrayList<>();
ViewColumn column = new ViewColumn();
column.setSql("select * from table");
columns.add(column);
viewConfig.setColumns(columns);
viewConfigModelList.add(viewConfig);

Integer year = 2022;
Integer quarter = 1;

Map<String, Object> result1 = new HashMap<>();
result1.put("id", 1);
result1.put("name", "John");
Map<String, Object> result2 = new HashMap<>();
result2.put("id", 2);
result2.put("name", "Jane");
List<Map<String, Object>> viewResultList = Arrays.asList(result1, result2);

when(viewResultMapper.selectDataView(column.getSql())).thenReturn(viewResultList);

// Act
LinkedHashMap<String, List<Map<String, Object>>> viewData = problemDataViewQueryEngine.queryViewData(viewConfigModelList, year, quarter);

// Assert
assertEquals(viewResultList, viewData.get("Sheet1"));
}
}

測評分析結果:

加分項:編譯正確;生成了1個測試用例,運行通過1個測試用例,行覆蓋率76%;

減分項:只生成一個測試用例,行覆蓋率不夠高;評分:76分。 

3)GLM-4
生成的單元測試如下。代碼編譯正確,生成了5個測試用例,行覆蓋率80%。

package ai.glm4;

import ai.demo.dao.mapper.ViewResultMapper;
import ai.demo.model.ViewColumn;
import ai.demo.model.ViewConfig;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.*;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class ProblemDataViewQueryEngineTestglm {

@InjectMocks
private ProblemDataViewQueryEngine engine;

@Mock
private ViewResultMapper viewResultMapper;

@Before
public void setUp() {
MockitoAnnotations.openMocks(this);
}

@Test(expected = IllegalArgumentException.class)
public void testQueryViewDataWithEmptyViewConfigModelList() {
engine.queryViewData(null, 2023, 1);
}

@Test(expected = IllegalArgumentException.class)
public void testQueryViewDataWithNullYear() {
List<ViewConfig> viewConfigModelList = new ArrayList<>();
engine.queryViewData(viewConfigModelList, null, 1);
}

@Test(expected = IllegalArgumentException.class)
public void testQueryViewDataWithNullQuarter() {
List<ViewConfig> viewConfigModelList = new ArrayList<>();
engine.queryViewData(viewConfigModelList, 2023, null);
}

@Test
public void testQueryViewData() {
List<ViewConfig> viewConfigModelList = Arrays.asList(new ViewConfig());
ViewColumn columnConfig = new ViewColumn();
columnConfig.setSql("SELECT * FROM table WHERE year = #{year} AND quarter = #{quarter}");
viewConfigModelList.get(0).setColumns(Arrays.asList(columnConfig));
viewConfigModelList.get(0).setSheet("Sheet1");

Map<String, Object> resultMap = new HashMap<>();
resultMap.put("column1", "value1");
List<Map<String, Object>> resultList = Arrays.asList(resultMap);

when(viewResultMapper.selectDataView(anyString())).thenReturn(resultList);

LinkedHashMap<String, List<Map<String, Object>>> viewData = engine.queryViewData(viewConfigModelList, 2023, 1);

assertNotNull(viewData);
assertEquals(1, viewData.size());
assertEquals(resultList, viewData.get("Sheet1"));

verify(viewResultMapper, times(1)).selectDataView(anyString());
}

@Test
public void testQueryViewDataWithCurrentYearAndQuarter() {
List<ViewConfig> viewConfigModelList = Arrays.asList(new ViewConfig());
ViewColumn columnConfig = new ViewColumn();
columnConfig.setSql("SELECT * FROM table WHERE year = #{currentyear} AND quarter = #{currentquarter}");
viewConfigModelList.get(0).setColumns(Arrays.asList(columnConfig));
viewConfigModelList.get(0).setSheet("Sheet1");

Map<String, Object> resultMap = new HashMap<>();
resultMap.put("column1", "value1");
List<Map<String, Object>> resultList = Arrays.asList(resultMap);

when(viewResultMapper.selectDataView(anyString())).thenReturn(resultList);

LinkedHashMap<String, List<Map<String, Object>>> viewData = engine.queryViewData(viewConfigModelList, 2023, 1);

assertNotNull(viewData);
assertEquals(1, viewData.size());
assertEquals(resultList, viewData.get("Sheet1"));

verify(viewResultMapper, times(1)).selectDataView(anyString());
}
}

測評分析結果:

加分項:編譯正確;生成了5個測試用例,運行通過5個測試用例,行覆蓋率80%;

減分項:行覆蓋率不夠高;評分:80分。 

4)GPT-3.5
生成的單元測試如下。代碼編譯正確,生成了1個測試用例,行覆蓋率76%。

package ai.gpt35;

import ai.demo.dao.mapper.ViewResultMapper;
import ai.demo.model.ViewColumn;
import ai.demo.model.ViewConfig;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;

public class ProblemDataViewQueryEngineTestgpt35 {

@Mock
private ViewResultMapper viewResultMapper;

@InjectMocks
private ProblemDataViewQueryEngine queryEngine;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}

@Test
public void testQueryViewData() {
// Mock data
List<ViewConfig> viewConfigModelList = new ArrayList<>();
ViewConfig viewConfig = new ViewConfig();
viewConfig.setSheet("TestSheet");
ViewColumn columnConfig = new ViewColumn();
columnConfig.setSql("SELECT * FROM TestTable");
List<ViewColumn> columns = new ArrayList<>();
columns.add(columnConfig);
viewConfig.setColumns(columns);
viewConfigModelList.add(viewConfig);

// Mock parameters
Integer year = 2023;
Integer quarter = 1;

// Mock result
List<Map<String, Object>> mockResult = new ArrayList<>();
// Add test data to mockResult

// Mock behavior
when(viewResultMapper.selectDataView(anyString())).thenReturn(mockResult);

// Perform the test
LinkedHashMap<String, List<Map<String, Object>>> result = queryEngine.queryViewData(viewConfigModelList, year, quarter);

// Verify behavior
verify(viewResultMapper, times(1)).selectDataView(anyString());

// Assertions
assertEquals(1, result.size()); // Check the size of the result map
assertEquals(mockResult, result.get("TestSheet")); // Check the result map content
}

// Add more test cases as needed
}

測評分析結果:

加分項:編譯正確;生成了1個測試用例,運行通過1個測試用例,行覆蓋率76%;

減分項:只生成1個測試用例,行覆蓋率不夠高;評分:76分。 

5)GPT-4-0613
生成的單元測試如下。代碼編譯正確,生成了4個測試用例,執行成功4個測試用例,行覆蓋率88%。

package ai.gpt4;

import ai.demo.dao.mapper.ViewResultMapper;
import ai.demo.model.ViewColumn;
import ai.demo.model.ViewConfig;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static org.mockito.Mockito.*;
import static org.junit.Assert.*;

public class ProblemDataViewQueryEngineTestGpt4 {

@Mock
private ViewResultMapper viewResultMapper;

@InjectMocks
private ProblemDataViewQueryEngine problemDataViewQueryEngine;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}

@Test(expected = IllegalArgumentException.class)
public void testQueryViewDataWithEmptyViewConfigModelList() {
problemDataViewQueryEngine.queryViewData(new ArrayList<>(), 2023, 1);
}

@Test(expected = IllegalArgumentException.class)
public void testQueryViewDataWithNullYear() {
List<ViewConfig> viewConfigModelList = new ArrayList<>();
viewConfigModelList.add(new ViewConfig());
problemDataViewQueryEngine.queryViewData(viewConfigModelList, null, 1);
}

@Test(expected = IllegalArgumentException.class)
public void testQueryViewDataWithNullQuarter() {
List<ViewConfig> viewConfigModelList = new ArrayList<>();
viewConfigModelList.add(new ViewConfig());
problemDataViewQueryEngine.queryViewData(viewConfigModelList, 2023, null);
}

@Test
public void testQueryViewData() {
// 構造測試數據
String sheetName = "TestSheet";
String sql = "SELECT * FROM table WHERE year=#{year} AND quarter=#{quarter}";
List<Map<String, Object>> mockResultList = new ArrayList<>();
Map<String, Object> mockResult = new LinkedHashMap<>();
mockResult.put("column1", "value1");
mockResultList.add(mockResult);

ViewColumn viewColumn = new ViewColumn();
viewColumn.setSql(sql);
List<ViewColumn> viewColumns = new ArrayList<>();
viewColumns.add(viewColumn);

ViewConfig viewConfig = new ViewConfig();
viewConfig.setSheet(sheetName);
viewConfig.setColumns(viewColumns);

List<ViewConfig> viewConfigModelList = new ArrayList<>();
viewConfigModelList.add(viewConfig);

// 配置Mockito行為
when(viewResultMapper.selectDataView(anyString())).thenReturn(mockResultList);

// 執行測試方法
LinkedHashMap<String, List<Map<String, Object>>> result = problemDataViewQueryEngine.queryViewData(viewConfigModelList, 2023, 1);

// 驗證結果
assertNotNull(result);
assertEquals(1, result.size());
assertTrue(result.containsKey(sheetName));
assertEquals(mockResultList, result.get(sheetName));

// 驗證Mockito交互
verify(viewResultMapper).selectDataView(anyString());
}
}

測評分析結果:

加分項:編譯正確;生成了4個測試用例,運行通過4個測試用例,行覆蓋率88%;

減分項:行覆蓋率不夠高;

評分:88分。

四、總結

大模型日期工具類報表數據填充代碼補全代碼優化代碼糾錯單元測試平均分
DeepSeek-Coder-33B80分50分85分85分80分90分78.3分
CodeLlama-70B60分80分60分80分50分76分67.7分
GLM-490分85分60分80分60分80分75.8分
GPT-3.590分50分80分85分80分76分76.8分
GPT-485分85分90分90分100分88分89.7分

可以看到,在Java編碼能力方面,GPT-4-0613 > DeepSeek-Coder-33B-Instruct > GPT-3.5 > GLM-4 > CodeLlama-70B-Instruct。整體來看,GPT-4在六項測評中都表現得比較穩定,其它四個大模型都存在在某項測評中表現不太穩定的情況。在編碼大模型的選型方面,如果追求性能,首選還是GPT-4,但是也比較貴。如果從安全性和性價比考慮的話,私有化部署開源編碼大模型DeepSeek-Coder-33B-Instruct應該是一個不錯的選擇。DeepSeek-Coder-33B-Instruct、GPT-3.5、GLM-4這三個大模型編碼能力比較接近,相差不大。至于CodeLlama-70B-Instruct,還是有點差距(小扎加油!)。從本次測評生成的具體代碼可以看出,在給出某個功能比較明確的需求設計說明,類似我們寫某個功能模塊的詳細設計這類的文檔之后,代碼大模型大部分情況可以快速實現這個功能需求。雖然實現的不一定好,在代碼的可復用性、可讀性、可擴展性方面還有所欠缺,但大部分也能達到初級程序員的水平,在算法優化方面甚至能達到中高級程序員水平。在實際使用過程中,可以通過代碼大模型來加快程序的開發。之前需要程序員完全自己實現代碼,現在可以先讓大模型輸出第一版,完成80%的代碼,在這個基礎上再去完善,提升研發效率。

以上通過代碼生成、代碼補全、代碼優化、代碼糾錯、單元測試這幾個方面,共6個測評案例,對大模型在Java編碼能力進行了測評分析。匯總出測評的得分表如下。

文章轉自微信公眾號@頂尖程序員

上一篇:

最新LangChain+GLM4開發AI應用程序系列(三):RAG檢索增強生成篇

下一篇:

GLM-4-Flash免費:在線微調GLM-4-Flash + Function Calling搭建法律知識庫
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費