【从零开始重学Java】第3天

发布时间 2024-01-05 18:09:35作者: 迷路的哨兵甲

前情提示

从零开始重学Java 第0天
从零开始重学Java 第1天
从零开始重学Java 第2天

表达式和流程控制语句

表达式

操作数

  • 常量 (只有简单数据类型和String)
  • 变量

运算符

  • 位运算只对字符char和整型生效

位运算1

  • Java里 <<(算术)左移 >>(算术)右移 >>>无符号(逻辑)右移

位运算2

  • 运算符优先次序
    • i++ i--
    • ++i --i ! ~
    • (cast) new
    • 乘除取余
    • 加减法
    • 二进制左右移
    • 大于 小于 类型 比较运算
    • 相等 不等 比较运算
    • 位运算
    • || &&

作为了解就好,实际写代码不会写过于复杂的表达式

表达式的提升和转换

数学函数

流控制

表达式语句

分支语句

循环语句

break与continue语句

注释语句

简单的输入输出

  • Scanner
  • NumberFormat DecimalFormat

数字格式化,实际工作大部分时候都用BigDecimal toPlainString 或者工具类解决了

第三章习题

  • Java中常用的运算符以及含义
  • Java中操作符的优先级
  • >>>与>>有什么区别,给出代码执行结果
int b1= 1;
int b2= 1;
b1 <<= 31;
b2 <<= 31;

b1 >>= 31;
b1 >>= 1;

b2 >>>= 31;
b2 >>>= 1;

逻辑右移,算术右移
这题给的代码太绕弯了,正常谁这么写运算代码,非常难读懂
正常应该这样写 b1 = b1 << 31;

从上往下结果依次是-2147483648 -2147483648 -1 -1 1 0
不需要追求位运算的熟练度,知道补码和运算原理就好,高级程序语言就是为了屏蔽底层,即使你能练到一眼看出运行结果,也没什么太大的意义

  • 设n为自然数,设计程序计算n的阶乘
    private static int factorial(int n) {
        int result = 1;
        for (int i = 1; i <= n; i++) {
            result *= i;
        }
        return result;
    }

  • 使用java.lang.Math生成100个0~99的随机数,找出最大者最小者,统计大于50的整数个数

其实用steam很方便,非大量数据的数组(万个以上),不需要太在乎循环次数,不会慢很多的

    private static void randomArray(){
        int[] randomNumberArray = new int[100];
        for (int i = 0; i < 100; i++) {
            int randomNumber = (int) (Math.random() * 100);
            randomNumberArray[i] = randomNumber;
        }

        System.out.println("随机数数组:" + Arrays.toString(randomNumberArray));

        int max = 0;
        int min = 100;
        int count = 0;
        for (int oneNumber : randomNumberArray) {
            if (oneNumber > max){
                max = oneNumber;
            }
            if (oneNumber < min){
                min = oneNumber;
            }
            if (oneNumber > 50){
                count++;
            }
        }
        System.out.println("单次循环的结果 max: " + max +" min:" + min + " count: " + count);

        int max1 = IntStream.of(randomNumberArray).max().getAsInt();
        int min1 = IntStream.of(randomNumberArray).min().getAsInt();
        long count1 = IntStream.of(randomNumberArray).filter(e ->  e>50).count();
        System.out.println("stream方式 max1: " + max1 +" min1:" + min1 + " count1: " + count1);
    }
  • 编写程序打印图案、打印乘法口诀表
1x1=1
1x2=2  2x2=4
1x3=3  2x3=6  3x3=9
1x4=4  2x4=8  3x4=12  4x4=16
1x5=5  2x5=10  3x5=15  4x5=20  5x5=25
1x6=6  2x6=12  3x6=18  4x6=24  5x6=30  6x6=36
1x7=7  2x7=14  3x7=21  4x7=28  5x7=35  6x7=42  7x7=49
1x8=8  2x8=16  3x8=24  4x8=32  5x8=40  6x8=48  7x8=56  8x8=64
1x9=9  2x9=18  3x9=27  4x9=36  5x9=45  6x9=54  7x9=63  8x9=72  9x9=81

* * * * * * *
* * * * * *
* * * * *
* * * *
* * *
* *
*

* * * * * * *
  * * * * *
    * * *
      *
    * * *
  * * * * *
* * * * * * *

上下对称的这种,分析好上下限,可以减少循环

    private static void printStarAnd99(int n){

        StringBuilder builder = new StringBuilder();
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= i; j++) {
                if (j != 1){
                    builder.append("\t");
                }
                builder.append(j).append("x").append(i).append("=").append(j*i);
            }
            builder.append("\n");
        }
        System.out.println(builder);


        builder.setLength(0);
        for (int i = n; i >= 1; i--) {
            for (int j = 1; j <= n; j++) {
                if (j > i){
                    continue;
                }
                if (j != 1){
                    builder.append(" ");
                }
                builder.append("*");
            }
            builder.append("\n");
        }
        System.out.println(builder);


        builder.setLength(0);
        //分割线
        int line = n/2;
        //上限
        int top;
        //下限
        int low;
        for (int i = 1; i <= n; i++) {
            if (i <= line){
                top = (n-i+1);
                low = i;
            }else {
                top = i;
                low = (n-i+1);
            }
            for (int j = 1; j <= n; j++) {
                if (j > top){
                    break;
                }
                if (j != 1){
                    builder.append(" ");
                }
                if (j >= low){
                    builder.append("*");
                }else {
                    builder.append(" ");
                }
            }
            builder.append("\n");
        }
        System.out.println(builder);
        builder.setLength(0);

    }
  • 编写程序判断是否回文、是否为素数、华氏温度转换摄氏度
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()){
            String line = scanner.nextLine();
            if ("stop".equals(line)){
                break;
            }
            judgeStr(line);
        }

    }

    private static void judgeStr(String str){
        if (isPalindrome(str)){
            System.out.println(str + " 是回文");
        }
        try {
            int anInt = Integer.parseInt(str);
            if (isPrime(anInt)){
                System.out.println(anInt + " 是质数");
            }
        }catch (Exception ignore){
            System.out.println(str + " 不是回文 也不是数字");
            return;
        }
        try {
            double aDouble = Double.parseDouble(str);
            System.out.println(aDouble + "华氏度 转 摄氏度 结果是" + fahrenheitToCelsius(aDouble));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private static boolean isPalindrome(String str) {
        //或者使用自带的方法
        // return str.equals(new StringBuilder(str).reverse().toString());

        int left = 0;
        int right = str.length() - 1;
        while (left < right) {
            if (str.charAt(left) != str.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
    private static boolean isPrime(int number) {
        if (number <= 1) {
            return false;
        }
        for (int i = 2; i <= Math.sqrt(number); i++) {
            if (number % i == 0) {
                return false;
            }
        }
        return true;
    }
    private static double fahrenheitToCelsius(double fahrenheit) {
        //C = (F - 32) * 5/9
        return (fahrenheit - 32) * 5 / 9;
    }
  • 编写程序,读入三角形边长判断面积
s=(a+b+c)/2
面积=根号下 s(s-a)(s-b)(s-c)
    private static double calculateTriangleArea(double a, double b, double c) {
        double s = (a + b + c) / 2; // 计算半周长
        double area = Math.sqrt(s * (s - a) * (s - b) * (s - c)); // 计算面积
        return area;
    }
  • 编写一个日期计算程序,输入月份,输出本月的月历,输入一个日期,显示星期几,输入两个日期则计算两个日期的间隔

使用java8的新DateTimeAPI,老掉牙的Date不要再使用了

    private static void judgeDate(String str){
        try {
            int anInt = Integer.parseInt(str);
            if (anInt > 12 || anInt < 1){
                System.out.println("月份不正确");
                return;
            }
            StringBuilder builder = new StringBuilder("日\t一\t二\t三\t四\t五\t六");
            builder.append("\n");
            LocalDate date = LocalDate.of(2024, anInt, 1);
            int dayOfWeekValue = date.getDayOfWeek().getValue();
            if (dayOfWeekValue != 7){
                for (int i = 0; i < dayOfWeekValue; i++) {
                    builder.append(" ").append("\t");
                }
            }
            LocalDate plusDate = date;
            while (plusDate.getMonthValue() == anInt){
                builder.append(plusDate.getDayOfMonth());
                if (plusDate.getDayOfWeek().getValue() != 6){
                    builder.append("\t");
                }else {
                    builder.append("\n");
                }
                plusDate = plusDate.plusDays(1);
            }
            System.out.println(builder);
            builder.setLength(0);
            return;
        }catch (Exception ignore){
        }

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String[] split = str.split(" ");
        if (split.length == 1){
            try {
                LocalDate date = LocalDate.parse(str, dateTimeFormatter);
                System.out.println(str + "是" + date.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINA));
            }catch (Exception e){
                System.out.println("日期格式不正确 " + str);
                return;
            }
        }else {
            try {
                LocalDate date0 = LocalDate.parse(split[0], dateTimeFormatter);
                LocalDate date1 = LocalDate.parse(split[1], dateTimeFormatter);
                System.out.println(date0 + " " + date1 + " 的相差天数为 " + Period.between(date0,date1).getDays());
            }catch (Exception e){
                System.out.println("多个日期格式不正确 " + split[0] + " " + split[1]);
            }
        }
    }
  • 有若干1元,2角,5分,1分的硬币,编写一个程序,对于任意输入的一个金额,给出能组合这个值的最佳可能,要求使用的币值个数最少

贪心
为什么用BigDecimal?因为浮点数运算会丢失精度

    private static void judgeMoney(String str){
        BigDecimal totalAmount;
        try {
            totalAmount = new BigDecimal(str);
        }catch (Exception e){
            System.out.println("金额数字格式不正确 "+ str);
            return;
        }
        //完全转换为整数来计算更方便
        int totalAmountFen = totalAmount
                .multiply(BigDecimal.TEN)
                .multiply(BigDecimal.TEN).intValue();

        int tempModMoney = 0;
        int[] moneyArray = {100,20,5,1};
        int[] moneyCountArray = {0,0,0,0};
        for (int i = 0; i < moneyArray.length; i++) {
            int count = totalAmountFen /moneyArray[i];
            tempModMoney = totalAmountFen %moneyArray[i];
            moneyCountArray[i] = count;
            if (tempModMoney == 0){
                break;
            }
            totalAmountFen = tempModMoney;
        }
        if (tempModMoney != 0){
            System.out.println("不能整除!剩余 " + tempModMoney);
        }

        System.out.println("1元的 " + moneyCountArray[0]);
        System.out.println("2角的 " + moneyCountArray[1]);
        System.out.println("5分的 " + moneyCountArray[2]);
        System.out.println("1分的 " + moneyCountArray[3]);

    }