HIT软件构造-Lab3中的函数技巧

目录

1.根据标签label移除所有的interval

2.做出一个选择函数alternative

3.app的代码结构

4.日期类的包装模式

5.HashSet的非无序性


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())));
    }
}

有任何问题和建议欢迎大家指出,不胜感激 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值