目录
1.根据标签label移除所有的interval
在MultiIntervalSet中一个标签可以对应很多时间段,所以不能移除一次标签就退出函数,但是在数组中移除元素肯定要对后面的循环造成影响。
(1) 不能使用增强for循环,否则会出现ConcurrentModificationException异常
(2) 不能使用迭代器同样会出现上述异常
(3) 使用索引i时会有一个问题,移除一个元素后整个后面元素的索引都会发生变化
可以使用如下形式解决,每次将n -- , i--,这样就能消除这个错误
/**
* @param label to remove
* @return 是否移除成功
*/
@Override
public boolean remove(L label){
boolean isRemove = false;
int n = intervalList.size();
for(int i = 0; i < n; i ++){
if(intervalList.get(i).label().equals(label)){
intervalList.remove(intervalList.get(i));
i --;
n --;
if(! isRemove)
isRemove = true;
}
}
checkRep();
return isRemove;
}
2.做出一个选择函数alternative
在做app时,有大量判断是否非法的选择,但是这些选择都有共性,就是先给出一条提示和选项,然后问选哪个,再判断有无此选项,没有的话给出警告,重新选择,我精心写了一个alternative函数来实现此功能,节省了一两百行的代码(select,sc等都是静态全局变量)
/**
* 对给出的选项作出一次选择
* @param issue 提示
* @param min 最小值
* @param max 最大值
* @param warning 选择不合理时的警告
* @return 作出的选择值
* @throws InputMismatchException 输出的不是整数
*/
public static int alternative(String issue, int min, int max, String warning) throws InputMismatchException{
System.out.println(issue);
boolean inputMatch;
do{
String str = sc.next();
try{
inputMatch = true;
select = Integer.parseInt(str);
}catch(NumberFormatException e){
System.out.println(e.toString());
System.out.println("重新输入:");
inputMatch = false;
}
if(inputMatch){
if(select < min || select > max)
System.out.println(warning);
else
break;
}
}while(true);
return select;
}
3.app的代码结构
三个app我的结构是尽量简化main函数,多包装函数,让main函数显得简单整洁并且一目了然,再尽量将变量全局化,静态化,减少变量调用。
main函数:
public static void main(String[] args){
init(); // 初始化整个系统
selectWay(); // 选择排班方式(手动还是自动)
if(select == 1)
autoArrange(); // 自动排班
else
manualArrange(); // 手动排班
}
autoArrange函数:
/**
* 自动排班
*/
public static void autoArrange(){
System.out.println("暂时没有员工,需要先添加员工");
addEmployee();
menu();
while(select == 2){
addEmployee();
menu();
}
roster.autoInsert();
System.out.println(roster);
System.out.println("自动排班完成,退出系统***********");
System.exit(0);
}
manualArrange函数:
/**
* 手动排班
*/
public static void manualArrange(){
while(! roster.checkEveryday(false)){
if(roster.employeeSet().isEmpty()){
System.out.println("暂时没有员工,需要先添加员工");
addEmployee();
}
menu();
if(select == 1) // 安排值班
arrange();
else if(select == 2) // 添加员工
addEmployee();
else
delEmployee();
}
System.out.println("手动排班完成,退出系统***********");
}
4.日期类的包装模式
lab3中的日期只涉及年月日,我们以后使用的日期也很少涉及时分秒,以及什么时区等乱七八糟的东西,用Calendar和Date类都十分的繁琐,而且西方他们月份是0-11,经常把我给整蒙了,所以针对这种情况,我写了一个MyDate,虽然简单,但是很是很实用(尤其是对我这种菜鸟很实用)
package Practise;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Objects;
public class MyDate{
private final Calendar calendar = new GregorianCalendar();
/**
* 构造方法 1
* @param year 年
* @param month 月 (中国式 1-12 月)
* @param date 日期
*/
public MyDate(int year, int month, int date){
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DATE, date);
}
/**
* 构造方法 2
* @param date 另一个日期
*/
public MyDate(MyDate date){
calendar.set(Calendar.YEAR, date.calendar.get(Calendar.YEAR));
calendar.set(Calendar.MONTH, date.calendar.get(Calendar.MONTH));
calendar.set(Calendar.DATE, date.calendar.get(Calendar.DATE));
}
/**
* @return 年
*/
public int year(){
return calendar.get(Calendar.YEAR);
}
/**
* @return 月
*/
public int month(){
return calendar.get(Calendar.MONTH);
}
/**
* @return 日
*/
public int date(){
return calendar.get(Calendar.DATE);
}
/**
* @param date 比较日期
* @return 相差了多少天,比date晚为正,早为负
*/
public int differentDays(MyDate date){
int day = 0;
MyDate date1 = new MyDate(date);
while(! this.equals(date1)){
if(this.after(date1)){
date1.calendar.add(Calendar.DATE, 1);
day ++;
}
else{
date1.calendar.add(Calendar.DATE, - 1);
day --;
}
}
return day;
}
/**
* @param date 另一个日期
* @return this是否在date的后面
*/
public boolean after(MyDate date){
return calendar.after(date.calendar);
}
public boolean before(MyDate date){
return calendar.before(date.calendar);
}
@Override
public boolean equals(Object o){
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
MyDate myDate = (MyDate)o;
return this.calendar.get(Calendar.YEAR) == myDate.calendar.get(Calendar.YEAR) && this.calendar.get(Calendar.MONTH) == myDate.calendar.get(Calendar.MONTH) && this.calendar.get(Calendar.DATE) == myDate.calendar.get(Calendar.DATE);
}
@Override
public int hashCode(){
return Objects.hash(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
}
@Override
public String toString(){
return calendar.get(Calendar.YEAR) + "年" + (calendar.get(Calendar.MONTH) + 1) + "月" + calendar.get(Calendar.DATE) + "日";
}
}
5.HashSet的非无序性
HashSet不是有序的,但也不是无序的,所以不能依靠HaseSet随机抽取一个元素,可以利用List的索引加上Random的随机数实现列表或数组中的随机数抽取
public class Main{
public static void main(String[] args) throws IOException {
HashSet<Integer> hashSet = new HashSet<>();
hashSet.add(1);
hashSet.add(2);
hashSet.add(3);
List<Integer> list = new ArrayList<>(hashSet);
System.out.println(list.get(new Random().nextInt(list.size())));
}
}
有任何问题和建议欢迎大家指出,不胜感激