天天看點

Java個人筆記

java環境搭建

linux環境

  • jdk1.8
    #編寫檔案
    vim  /etc/profile
    
    export JAVA_HOME=/usr/local/jdk1.8.0_191
    export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:
    export PATH=$JAVA_HOME/bin:$PATH
    
    #使配置檔案生效
    source /etc/profile
               
  • jdk14
    win10 jdk14 配置已經不需要 jre 和 class_home了
    JAVA_HOME    E:\JAVA\jdk-14
    Path   %JAVA_HOME%\bin
               
    centos jdk14 環境變量配置
    #編寫檔案
    vim  /etc/profile
    #使配置檔案生效
    source /etc/profile
               
    JAVA_HOME=/usr/local/java/jdk-14
    export PATH=$JAVA_HOME/bin:$PATH
               

TreeSet 對一個實體類進行排序

HashSet 無序唯一,TreeSet 有序唯一

HashSet<NavigationTable> navigationTableHashSet = new HashSet<>();
	....省略(導航欄代碼)
TreeSet<NavigationTable> youxu = new TreeSet<>(navigationTableHashSet);

------------------------------
實體類
public class NavigationTable implements Comparable<NavigationTable> {
	.....省略實體
	
@Override           //對實體類的id進行排序
	public int compareTo(NavigationTable o) {
		int a = this.getId() - o.getId();
		return a;
	}
}
           

Java中Double保留後小數位的幾種方法

Java中Double保留後小數位的幾種方法網頁位址

java擷取當天,前天,明天,本周,本月,本年的開始日期時間和結束日期時間

java擷取當天,前天,明天,本周,本月,本年的開始日期時間和結束日期時間

Math

  1. 舍掉小數取整:Math.floor(3.5)=3
  2. 四舍五入取整:Math.rint(3.5)=4
  3. 進位取整:Math.ceil(3.1)=4
  4. 取絕對值:Math.abs(-3.5)=3.5
  5. 取餘數:A%B = 餘數

疊代器

.next()在一個循環了不要出現兩次,不然會越界。本人已經體驗過了。在此做個記錄
Iterator it = jsonObject.entrySet().iterator();
List<String> zgBm = new ArrayList<>();
while (it.hasNext()) {
    Map.Entry entry = (Map.Entry) it.next();
    if (entry.getValue().toString().equals("true")) {
        zgBm.add(entry.getKey().toString());
    }
}
           

local日期常用方法

getYear()    int    擷取目前日期的年份
getMonth()    Month    擷取目前日期的月份對象
getMonthValue()    int    擷取目前日期是第幾月
getDayOfWeek()    DayOfWeek    表示該對象表示的日期是星期幾
getDayOfMonth()    int    表示該對象表示的日期是這個月第幾天
getDayOfYear()    int    表示該對象表示的日期是今年第幾天
withYear(int year)    LocalDate    修改目前對象的年份
withMonth(int month)    LocalDate    修改目前對象的月份
withDayOfMonth(int dayOfMonth)    LocalDate    修改目前對象在當月的日期
isLeapYear()    boolean    是否是閏年
lengthOfMonth()    int    這個月有多少天
lengthOfYear()    int    該對象表示的年份有多少天(365或者366)
plusYears(long yearsToAdd)    LocalDate    目前對象增加指定的年份數
plusMonths(long monthsToAdd)    LocalDate    目前對象增加指定的月份數
plusWeeks(long weeksToAdd)    LocalDate    目前對象增加指定的周數
plusDays(long daysToAdd)    LocalDate    目前對象增加指定的天數
minusYears(long yearsToSubtract)    LocalDate    目前對象減去指定的年數
minusMonths(long monthsToSubtract)    LocalDate    目前對象減去注定的月數
minusWeeks(long weeksToSubtract)    LocalDate    目前對象減去指定的周數
minusDays(long daysToSubtract)    LocalDate    目前對象減去指定的天數
compareTo(ChronoLocalDate other)    int    比較目前對象和other對象在時間上的大小,傳回值如果為正,則目前對象時間較晚,
isBefore(ChronoLocalDate other)    boolean    比較目前對象日期是否在other對象日期之前
isAfter(ChronoLocalDate other)    boolean    比較目前對象日期是否在other對象日期之後
isEqual(ChronoLocalDate other)    boolean    比較兩個日期對象是否相等


// 擷取今天的日期
LocalDate now = LocalDate.now();
// 今天是幾号
int dayofMonth = now .getDayOfMonth();
// 今天是周幾(傳回的是個枚舉類型,需要再getValue())
int dayofWeek = now .getDayOfWeek().getValue();
// 今年是哪一年
int dayofYear = now .getDayOfYear();
// 取本月第1天:
LocalDate firstDayOfThisMonth=now .with(TemporalAdjusters.firstDayOfMonth()); 
// 取本月第2天:
LocalDate secondDayOfThisMonth = now .withDayOfMonth(2);
// 取本月最後一天,再也不用計算是28,29,30還是31:
LocalDate lastDayOfMonth=now .with(TemporalAdjusters.lastDayOfMonth()); 
// 取下一天:
LocalDate firstDayOfNextMonth = lastDayOfMonth.plusDays(1);
// 取2019年1月第一個周一:
LocalDate firstMondayOf2017 = LocalDate.parse("2019-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); 
//本月的第一天
LocalDate monthFirstDay = LocalDate.of(now.getYear(),now.getMonth(),1);
 //本月的最後一天
LocalDate monthLastDay =now.with(TemporalAdjusters.lastDayOfMonth());
//上月的第一天
LocalDate date = now.minusMonths(1).withDayOfMonth(1);
//上月的最後一天
LocalDate date1 = date.with(TemporalAdjusters.lastDayOfMonth());
           

LocalDateTime

LocalDateTime now = LocalDateTime.now();
System.out.println("計算兩個時間的差:");
LocalDateTime end = LocalDateTime.now();
Duration duration = Duration.between(now,end);
long days = duration.toDays(); //相差的天數
long hours = duration.toHours();//相差的小時數
long minutes = duration.toMinutes();//相差的分鐘數
long millis = duration.toMillis();//相差毫秒數
long nanos = duration.toNanos();//相差的納秒數
System.out.println(now);
System.out.println(end);

System.out.println("發送短信耗時【 "+days+"天:"+hours+" 小時:"+minutes+" 分鐘:"+millis+" 毫秒:"+nanos+" 納秒】");


//計算兩個日期之間是的差額
LocalDate localDate = LocalDate.now();
LocalDate localDate2 = localDate.minusYears(5).minusMonths(10).minusDays(2);
Period next = Period.between(localDate2,localDate);
log.info("---------------年--------------------");
log.info(String.valueOf(next.getYears()));
log.info("---------------月--------------------");
log.info(String.valueOf(next.getMonths()));
log.info("----------------天-------------------");
log.info(String.valueOf(next.getDays()));

//擷取目前系統的時區
OffsetDateTime.now().getOffset();  //輸出 "+08:00" 不同時區輸出不同值
//擷取當天開始時間的時間戳
LocalDateTime.of(LocalDate.now(),LocalTime.MIN).toInstant(OffsetDateTime.now().getOffset()).toEpochMilli();
//擷取當天結束時間的時間戳
LocalDateTime.of(LocalDate.now(), LocalTime.MAX).toInstant(OffsetDateTime.now().getOffset()).toEpochMilli();
           

例子-計算時間(可以參考)

/**
     * 計算時間類型
     *
     * @param days       天
     * @param startDateL 使用者開始時間
     * @param endDateL   使用者結束時間
     * @return {@link List<Object>}
     */
    public static List<Object> toCalculateTypeTime(Integer days, Long startDateL, Long endDateL) {
        List<Object> res = new ArrayList<>();
        int type = 1; //1查小時 2查天
        LocalDateTime nowDateTime = LocalDateTime.now();
        //傳回小時
        if ((Objects.nonNull(days) && days.equals(1))
                || (Objects.nonNull(startDateL) && Objects.nonNull(endDateL) && startDateL.equals(endDateL))) {
            LocalDateTime startDateTime = null;
            LocalDateTime endDateTime = null;
            if (Objects.nonNull(days)) {
                startDateTime = nowDateTime.of(LocalDate.now(), LocalTime.MIN).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
                endDateTime = nowDateTime.of(LocalDate.now(), LocalTime.MAX).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
            }
            if (Objects.nonNull(startDateL) && Objects.nonNull(endDateL)) {
                LocalDate startDate = LocalDateTime.ofEpochSecond(startDateL, 0, ZoneOffset.ofHours(8)).toLocalDate();
                startDateTime = LocalDateTime
                        .of(startDate,LocalTime.MIN)
                        .atZone(ZoneOffset.ofHours(8))
                        .toLocalDateTime();
                LocalDate endDate = LocalDateTime.ofEpochSecond(endDateL, 0, ZoneOffset.ofHours(8)).toLocalDate();
                endDateTime = LocalDateTime
                        .of(endDate, LocalTime.MAX)
                        .atZone(ZoneOffset.ofHours(8))
                        .toLocalDateTime();
            }
            if (Objects.isNull(startDateTime) || Objects.isNull(endDateTime)) {
                return null;
            }
            res.add(type);
            res.add(startDateTime);
            res.add(endDateTime);
            return res;
        }
        //傳回天
        type = 2;
        LocalDate startDate = null;
        LocalDate endDate = null;
        if (Objects.nonNull(days) && (Objects.isNull(startDateL) || Objects.isNull(endDateL))) {
            LocalDateTime minusDays = nowDateTime.minusDays(days);
            startDate = minusDays.atZone(ZoneOffset.ofHours(8)).toLocalDate();
            endDate = nowDateTime.atZone(ZoneOffset.ofHours(8)).toLocalDate();
            res.add(type);
            res.add(startDate);
            res.add(endDate);
            return res;
        } else if (Objects.isNull(days) && Objects.nonNull(startDateL) || Objects.nonNull(endDateL)) {
            startDate = LocalDateTime.ofEpochSecond(startDateL, 0, ZoneOffset.ofHours(8)).toLocalDate();
            endDate = LocalDateTime.ofEpochSecond(endDateL, 0, ZoneOffset.ofHours(8)).toLocalDate();
            res.add(type);
            res.add(startDate);
            res.add(endDate);
            return res;
        }
        type = 0;
        res.add(type);
        return res;
    }
           

校驗身份證

//校驗身份證
    final static Map<Integer, String> zoneNum = new HashMap<>();
    final static int[] PARITYBIT = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
    final static int[] POWER_LIST = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10,
            5, 8, 4, 2};
    static {
        zoneNum.put(11, "北京");
        zoneNum.put(12, "天津");
        zoneNum.put(13, "河北");
        zoneNum.put(14, "山西");
        zoneNum.put(15, "内蒙古");
        zoneNum.put(21, "遼甯");
        zoneNum.put(22, "吉林");
        zoneNum.put(23, "黑龍江");
        zoneNum.put(31, "上海");
        zoneNum.put(32, "江蘇");
        zoneNum.put(33, "浙江");
        zoneNum.put(34, "安徽");
        zoneNum.put(35, "福建");
        zoneNum.put(36, "江西");
        zoneNum.put(37, "山東");
        zoneNum.put(41, "河南");
        zoneNum.put(42, "湖北");
        zoneNum.put(43, "湖南");
        zoneNum.put(44, "廣東");
        zoneNum.put(45, "廣西");
        zoneNum.put(46, "海南");
        zoneNum.put(50, "重慶");
        zoneNum.put(51, "四川");
        zoneNum.put(52, "貴州");
        zoneNum.put(53, "雲南");
        zoneNum.put(54, "西藏");
        zoneNum.put(61, "陝西");
        zoneNum.put(62, "甘肅");
        zoneNum.put(63, "青海");
        zoneNum.put(64, "新疆");
        zoneNum.put(71, "台灣");
        zoneNum.put(81, "香港");
        zoneNum.put(82, "澳門");
        zoneNum.put(91, "外國");
    }
    /**
     * @Description: 校驗身份證是否合法
     * @Param: [certNo]
     * @return: boolean
     * @Author: 劉俊秦
     * @Date: 2019/6/3 0003
     */
    public static boolean isIDCard(String certNo) {
        if (certNo == null || (certNo.length() != 15 && certNo.length() != 18))
            return false;
        final char[] cs = certNo.toUpperCase().toCharArray();
        //校驗位數
        int power = 0;
        for (int i = 0; i < cs.length; i++) {
            if (i == cs.length - 1 && cs[i] == 'X')
                break;//最後一位可以 是X或x
            if (cs[i] < '0' || cs[i] > '9')
                return false;
            if (i < cs.length - 1) {
                power += (cs[i] - '0') * POWER_LIST[i];
            }
        }

        //校驗區位碼
        if (!zoneNum.containsKey(Integer.valueOf(certNo.substring(0, 2)))) {
            return false;
        }

        //校驗年份
        String year = certNo.length() == 15 ? getIdcardCalendar() + certNo.substring(6, 8) : certNo.substring(6, 10);

        final int iyear = Integer.parseInt(year);
        if (iyear < 1900 || iyear > Calendar.getInstance().get(Calendar.YEAR))
            return false;//1900年的PASS,超過今年的PASS

        //校驗月份
        String month = certNo.length() == 15 ? certNo.substring(8, 10) : certNo.substring(10, 12);
        final int imonth = Integer.parseInt(month);
        if (imonth < 1 || imonth > 12) {
            return false;
        }

        //校驗天數
        String day = certNo.length() == 15 ? certNo.substring(10, 12) : certNo.substring(12, 14);
        final int iday = Integer.parseInt(day);
        if (iday < 1 || iday > 31)
            return false;

        //校驗"校驗碼"
        if (certNo.length() == 15)
            return true;
        return cs[cs.length - 1] == PARITYBIT[power % 11];
    }

    private static int getIdcardCalendar() {
        GregorianCalendar curDay = new GregorianCalendar();
        int curYear = curDay.get(Calendar.YEAR);
        int year2bit = Integer.parseInt(String.valueOf(curYear).substring(2));
        return year2bit;
    }
           

根據身份證号計算年齡

/**
     * @Description: 根據身份證号計算年齡
     * @Param: [pensonnelIdCard]
     * @return: java.lang.Integer
     * @Author: 劉俊秦
     * @Date: 2019/6/3 0003
     */
    public static Integer getPersonAgeFromIdCard(String pensonnelIdCard) {

        //截取身份證中出行人出生日期中的年、月、日
        Integer personYear = Integer.parseInt(pensonnelIdCard.substring(6, 10));
        Integer personMonth = Integer.parseInt(pensonnelIdCard.substring(10, 12));
        Integer personDay = Integer.parseInt(pensonnelIdCard.substring(12, 14));

        Calendar cal = Calendar.getInstance();
        // 得到目前時間的年、月、日
        Integer yearNow = cal.get(Calendar.YEAR);
        Integer monthNow = cal.get(Calendar.MONTH) + 1;
        Integer dayNow = cal.get(Calendar.DATE);

        // 用目前年月日減去生日年月日
        Integer yearMinus = yearNow - personYear;
        Integer monthMinus = monthNow - personMonth;
        Integer dayMinus = dayNow - personDay;

        Integer age = yearMinus; //先大緻指派

        if (yearMinus == 0) { //出生年份為目前年份 
            age = 0;
        } else { //出生年份大于目前年份
            if (monthMinus < 0) {//出生月份小于目前月份時,還沒滿周歲
                age = age - 1;
            }
            if (monthMinus == 0) {//目前月份為出生月份時,判斷日期
                if (dayMinus < 0) {//出生日期小于目前月份時,沒滿周歲
                    age = age - 1;
                }
            }
        }
        return age;
    }
           

枚舉enum的使用(與在switch中的使用)

看看枚舉類

/**
 * 操作碼類
 * @author kokJuis
 * @version 1.0
 * @date 2017-3-6
 */
public enum Code {
 
    SUCCESS(10000, "操作成功"), 
    FAIL(10001, "操作失敗"), 
 
 
    private int code;
    private String msg;
 
    //為了更好的傳回代号和說明,必須呀重寫構造方法
    private Code(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
 
    public int getCode() {
        return code;
    }
 
    public void setCode(int code) {
        this.code = code;
    }
 
    public String getMsg() {
        return msg;
    }
 
    public void setMsg(String msg) {
        this.msg = msg;
    }
 
    
    // 根據value傳回枚舉類型,主要在switch中使用
    public static Code getByValue(int value) {
        for (Code code : values()) {
            if (code.getCode() == value) {
                return code;
            }
        }
        return null;
    }
    
}
           

使用:

//擷取代碼
int code=Code.SUCCESS.getCode();
//擷取代碼對應的資訊
String msg=Code.SUCCESS.getMsg();
 
//在switch中使用通常需要先擷取枚舉類型才判斷,因為case中是常量或者int、byte、short、char,寫其他代碼編譯是不通過的
 
int code=Code.SUCCESS.getCode();
 
switch (Code.getByValue(code)) {
 
    case SUCCESS:
        //......
    break;
 
    case FAIL:
        //......
    break;
 
}
           

數組和集合中行列互換的解法

分析過程

  • 主對角線是保持不變
  • 行列互換即角标互換:[0][1] => [1][0]
  • 循環次數:外層循環行,内層循環每一行的列

示意圖

Java個人筆記
//數組的情況
int arry[][] = new int[][] {{1,2,3},{4,5,6},{7,8,9}};
//這裡arry為什麼要減一呢,因為對角線是不用換的,所有去掉最後一次循環
for(int i=0; i< arry.length-1; i++) {
			//列循環從:i+1開始,提高循環效率
	for(int j=i+1; j< arry[i].length; j++) {
			int temp = arry[i][j];
			arry[i][j] = arry[j][i];
			arry[j][i] = temp;
	}
}

//集合的情況(具體數值就比列舉了,和數值差不多)
for (var i = 0; i < arr.size() - 1; i++) {
    for (var j = i + 1; j < arr.get(i).size(); j++) {
            int temp = arr.get(i).get(j);
            arr.get(i).set(j, arr.get(j).get(i));
            arr.get(j).set(i, temp);
     }
 }

           

java 鎖

java 鎖

java多線程

  • 帶傳回值的多線程調用,例子:
    //線程組
        List<Callable<String>> callables = new ArrayList<>();
    
        for (int i = 0; i < 10; i++) {
            Callable<String> myCallable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    int successCount = 0;
                    int errorCount = 0;
                    for (int j = 0; j < 30; j++) {
                    	//本人調用百度的方法(可以忽略,使用自己的邏輯)
                        BdSearchResVo search = BaiduApiUtil.search(image, imageType, groupIdList, null);
                        if (search.getError_code().equals(0)) {
                            successCount++;
                        } else {
                            errorCount++;
                        }
    
                    }
                    return "總成功:" + successCount + ",總失敗:" + errorCount;
                }
            };
            callables.add(myCallable);
        }
        //取到線程的所有資訊
        List<Future<String>> futures = executorService.invokeAll(callables);
        for (Future<String> f : futures) {
            LogPrintUtil.logRes(f.get());
        }
        //停止線程添加任務
        executorService.shutdown();
               
線程交替輸出
public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        for (int i = 9; i > -1; i--) {
            stack.add(i);
        }

        OutputData outputData = new OutputData(stack);
        new Thread(outputData).start();
        new Thread(outputData).start();
    }

    static class OutputData implements Runnable {

        private Stack<Integer> stack;

        Integer zhi1 = null;
        Integer zhi2 = null;

        public OutputData(Stack<Integer> stack) {
            this.stack = stack;

        }

        @Override
        public void run() {
            while (!stack.isEmpty()) {
                String name = Thread.currentThread().getName();
                synchronized (this) {
                    notify();
                    if (name.equals("Thread-0")) {
                        zhi1 = stack.peek();
                    }else {
                        zhi2 = stack.peek();
                    }
                    System.out.println(name + "---" + stack.pop());
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (name.equals("Thread-0")) {
                    System.out.println("乘積:" + zhi1 * zhi2);
                }
            }
        }

    }
           

輸出效果:

Java個人筆記

List集合

集合的排序

注意:集合直接點sort 方法會使集合失去序列化的效果。

解決方法可以使用 Collections.sort(); 解決不能序列化的問題

//匿名寫法
movieScores.sort((o1, o2) -> -(o1.getRating().intValue() - o2.getRating().intValue()));

//解決序列化問題
Collections.sort(movieScores,(o1, o2) -> -(o1.getRating().intValue() - o2.getRating().intValue()));

//還有一種解決辦法 使用 fastjson 重新序列化
userRecs.setMovieScores(
        JSON.parseArray(
                JSON.toJSONString(movieScores),
                MovieScore.class
        )
);

//簡潔排序
//Comparator.reverseOrder() 相反的順序-倒序
List<Integer> newSorts = temporarySorts
                    .stream()
                    .sorted(Comparator.reverseOrder())
                    .collect(Collectors.toList())
           

集合截取

注意:集合直接點subList 方法會使集合失去序列化的效果。

//集合截取
movieScores = movieScores.subList(0, 5);

//還有一種解決辦法 使用 fastjson 重新序列化
userRecs.setMovieScores(
        JSON.parseArray(
                JSON.toJSONString(movieScores),
                MovieScore.class
        )
);
           

流式程式設計(各種使用例子)

轉map的例子
//單個封裝
List<UserProfileResult> userProfileResults = userApiService.findByIds(userIdList);
//封裝一下參數
Map<Long, String> userProfileResultMap = userProfileResults
       	.stream()
       	.collect(Collectors.toMap(UserProfile::getUserId, UserProfile::getName))

//Function.identity() 這個實體的所有資料我都要
List<UserProfileResult> userProfileResults = userApiService.findByIds(userIdList);
//封裝一下參數
Map<Long, UserProfileResult> userProfileResultMap = userProfileResults
       	.stream()
       	.collect(Collectors.toMap(UserProfile::getUserId, Function.identity()))