Java练习题

20240506

实现一个方法 transform, 以数组为参数, 循环将数组中的每个元素 乘以 2 , 并设置到对应的数组元素上. 例如 原数组为 {1, 2, 3}, 修改之后为 {2, 4, 6}

    public static void transform(int[] array){
        for (int i = 0; i < array.length; i++) {
            array[i] *= 2;
        }
    }
    public static void main(String[] args) {
        int[] array = {1,2,3};
        transform(array);
        System.out.println(Arrays.toString(array));
    }

结果:


调整数组顺序使得奇数位于偶数之前。调整之后,不关心大小顺序。

如数组:[1,2,3,4,5,6]

调整后可能是:[1, 5, 3, 4, 2, 6]

    public static void test(int[] array){
        int i = 0;
        int j = array.length - 1;
        while(i < j){
            while(i < j && array[i] % 2 != 0){
                i++;
            }
            while(i < j && array[j] % 2 == 0){
                j--;
            }
            int tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
        }
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6};
        test(array);
        System.out.println(Arrays.toString(array));
    }

解析:


给定一个有序整型数组, 实现二分查找

    public static int binarySearch(int[] array,int key){
        int left = 0;
        int right = array.length - 1;
        while(left <= right){
            int mid = (left + right)/2;
            if(array[mid] < key){
                left = mid + 1;
            }else if(array[mid] > key){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7,8,9,10};
        int ret = binarySearch(array,3);
        if(ret == -1){
            System.out.println("not found");
        }else{
            System.out.println("找到了,下标是:"+ ret);
        }
    }

 给定一个整型数组,实现冒泡排序(升序)

错误示例:

 正确示例:

    public static void bubbleSort(int[] arr){
        boolean flg = false;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
                if(arr[j] > arr[j+1]){
                    int tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                    flg = true;
                }
            }
            if(flg == false){
                break;
            }
        }
    }
    public static void main(String[] args) {
        int[] arr = {1,3,2,2,4};
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));
    }

 解析:

进一步进行了优化,当数据在排序过程当中有序了,会在某一趟排序后,发现数据没有交换。

所以,每一趟排序完,都去检查是否发生了交换,没有交换证明数据已近有序,不需要再进行剩余趟数的排序了。


给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

下面是自己实现:

    public static int[] test(int[] arr,int target){
        for(int i=0;i<arr.length-1;i++){
            for(int j = i+1;j<arr.length;j++){
                if(arr[i] + arr[j] == target){
                    return new int[]{i,j};
                }
            }
        }
        return null;
    }

    public static void main(String[] args) {
        int[] nums = {2,7,11,15};
        int[] arr = test(nums,9);
        System.out.println(Arrays.toString(arr));
    }

下面是答案实现:

本题最重要的一句话:假设每种输入只会对应一个答案

也就意味着不会有多个答案,暴力求解就是挨个匹配查找即可

    public static int[] twoSum(int[] nums,int target){
        int[] result = new int[2];
        //双向指针i和j,i从前向后遍历,j从后向i遍历
        //若arr[i]+arr[j]=target,即为题解
        for(int i=0;i<nums.length-1;i++){
            for(int j = nums.length - 1;j > i;j--){
                if(nums[i] + nums[j] == target){
                    result[0] = i;
                    result[1] = j;
                }
            }
        }
        return result;
    }
    public static void main(String[] args) {
        int[] nums = {2,7,11,15};
        int[] arr = twoSum(nums,9);
        System.out.println(Arrays.toString(arr));
    }

 可以用哈希表来提升效率,后面学习之后再来改进


给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

下面是自己实现:

    public static int test(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            int x = arr[i];
            int j = 0;
            int count = 0;
            while(j < arr.length){
                if(arr[j] == x){
                    count++;
                    //这里加了判断若count已经大于1,提前结束循环
                    if(count > 1){  
                        break;
                    }
                }
                j++;
            }
            if(count == 1){
                return x;
            }
        }
            return -1;
    }
    public static void main(String[] args) {
        int[] arr = {2,2,1,3,4,3,8,4,8,2,9,2,9};
        int tmp = test(arr);
        if(tmp == -1){
            System.out.println("没找到");
        }else{
            System.out.println("找到了,该数字是:" + tmp);
        }
    }

 下面是答案实现:

本题主要考察运算符:异或。

异或的特点是:

1、n ^ n = 0;即两个相同的数字异或是0

2、0 ^ n = n;即0和任何数字进行异或,结果就是那个任何数字。

    public static int singleNumber(int[] nums){
        //用异或运算的性质可以巧妙的解决这个问题
        //因为数组中只有一个数字出现一次
        //则其他出现两次的数字用异或运算后都是0
        //最终整个数组异或运算的结果即为所求
        int ret = 0;
        for(int i : nums){
            ret ^= i;
        }
        return ret;
    }
    public static void main(String[] args) {
        int[] arr = {4,1,2,1,2};
        int tmp = singleNumber(arr);
        if(tmp == 0){
            System.out.println("没找到");
        }else{
            System.out.println("找到了,该数字是:" + tmp);
        }
    }

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素

例子:

自己实现:

    public static int test(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            int x = arr[i];
            int j = 0;
            int count = 0;
            while(j < arr.length){
                if(arr[j] == x){
                    count++;
                    //这里加了判断若count已经大于数组长度的1/2,提前结束循环
                    if(count > arr.length/2){
                        return x;
                    }
                }
                j++;
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        int[] arr = {2,2,1,1,1,2,2};
        int tmp = test(arr);
        if(tmp == -1){
            System.out.println("没找到");
        }else{
            System.out.println("找到了,该数字是:" + tmp);
        }
    }

 答案实现:

数组中出现次数超过一半的数字,一定是排好序之后,中间位置的数字。

    //将数组排序后,数组n/2的元素一定是众数
    public static int majorityElement(int[] arr) {
        Arrays.sort(arr);
        return arr[arr.length/2];
    }
    public static void main(String[] args) {
        int[] arr = {2,2,1,1,1,2,2};
        int tmp = majorityElement(arr);
        System.out.println(tmp);
    }

给你一个整数数组 arr,请你判断数组中是否存在连续三个元素都是奇数的情况:如果存在,请返回 true ;否则,返回 false 。 

自己实现:

    public static boolean test(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            int x = arr[i];
            int j = 0;
            int count = 0;
            while(j < arr.length){
                if(arr[j] % 2 != 0){
                    count++;
                    //这里加了判断若count已经大于数组长度的1/2,提前结束循环
                    if(count > 2){
                        return true;
                    }
                }else{
                    count = 0;
                }
                j++;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        int[] arr = {1,2,34,3,4,5,7,23,12};
        boolean tmp = test(arr);
        if(tmp == false){
            System.out.println("不存在连续三个元素都是奇数的情况");
        }else{
            System.out.println("存在连续三个元素都是奇数的情况");
        }
    }

答案实现: 

数字是连续出现的,所以我们只需要定义一个计数器,如果连续出现的次数超过3,则返回true。

    public static boolean threeConsecutiveOdds(int[] arr){
        //引入标记位记录连续出现奇数的个数
        int count = 0;
        for (int i = 0; i < arr.length; i++) {
            if(isConsecutiveOdd(arr[i])){
                //出现奇数,count++;
                count++;
                if(count == 3){
                    //出现连着三个奇数,返回true
                    return true;
                }
            }else{
                //碰到偶数,count重置
                count = 0;
            }
        }
        return false;
    }
    public static boolean isConsecutiveOdd(int num){
        return num % 2 != 0;
    }
    public static void main(String[] args) {
        int[] arr = {1,2,34,3,4,5,7,23,12};
        boolean tmp = threeConsecutiveOdds(arr);
        if(tmp == false){
            System.out.println("不存在连续三个元素都是奇数的情况");
        }else{
            System.out.println("存在连续三个元素都是奇数的情况");
        }
    }

获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列。

思路:

一个数的二进制位数为32,下标为0~31

想要得到一个整数中的每一个二进制数字,只有让它每个二进制数字都按位与(&)上1

按位与:与0得0,与1得1

代码如下:需要注意的是for循环的开始条件与结束条件

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个数字:");
        int n = sc.nextInt();
        //从左往右数
        System.out.print("二进制奇数位:");
        for (int i = 31; i >= 1 ; i-=2) {
            System.out.print(((n>>i) & 1) + " ");
        }

        System.out.println();//换行

        System.out.print("二进制偶数位:");
        for (int i = 30; i >= 0 ; i-=2) {
            System.out.print(((n>>i) & 1) + " ");
        }
    }

猜数字游戏


20240510

关于包的说法,下列错误的是:

 

如下代码的输出结果是什么?

public class Test { 
    public int aMethod(){
        static int i = 0;
        i++; 
        return i;
    } 
public static void main(String args[]){
    Test test = new Test(); 
    test.aMethod(); 
    int j = test.aMethod();
    System.out.println(j);
    } 
}

20240514_继承_work 

1、如下代码的 结果是什么 ?

class Base {
  Base() {
  	System.out.print("Base"); 
  }
}

public class Alpha extends Base {
 
  public static void main( String[] args ) {
    new Alpha();//1
    //调用父类无参的构造方法
    new Base();//2
  } 
}

 

在子类中每次创建新的对象,都会调用一次父类中的构造方法


2、A 派生出子类 B , B 派生出子类 C ,并且在 java 源代码有如下声明:

1. A a0=new A();

2. A a1=new B();

3. A a2=new C();

问以下哪个说法是正确的?()

A.只有第一行能通过编译

B.第1、2行能通过编译,但第3行编译出错

C.第1、2、3行能通过编译,但第2、3行运行时出错

D.第1行,第2行和第3行的声明都是正确的

解析:

主要疑问就是注释3处,此时A虽然不是C的直接父类,但是C依然间接继承了A的内容的,此时可以发生向上转型的。

故:选择D。


3、以下程序执行的结果是:

class X{
	Y y=new Y();//1
	public X(){//2
		System.out.print("X");
	}
}
class Y{
	public Y(){//3
		System.out.print("Y");
	}
}
public class Z extends X{
	Y y=new Y();//4
	public Z(){//5
		System.out.print("Z");
	}
	public static void main(String[] args) {
		new Z();
	}
}

A.ZYXX

B.ZYXY

C.YXYZ

D.XYZX

解析:

本题考察代码的执行顺序:

类Z继承类X。

在继承层次上,先执行父类和子类的静态的,再执行父类的实例,父类的构造,最后执行子类的实例和子类的构造。

根据以上顺序,我们得出结论:本题中没有静态的。所以先执行1和2,再执行4和5。执行注释1和注释4的时候,分班打印Y。故最终的结果是YXYZ。

故答案为:C


20240517——多态

以下代码运行输出的是

class B {
    public int Func() {
        System.out.print("B");
        return 0;
    }
}
class D extends B {
    @Override
    public int Func() {
        System.out.print("D");
        return 0;
    }
}
public class Test {
    public static void main(String[] args) {
        B a = new B();
        B b = new D();
        a.Func();
        b.Func();
    }
}

解析:向上转型,用父类引用创建的子类对象,在调用func方法时,发生动态绑定,调用的是子类中重写的方法


2024-05-18_抽象类和接口

public interface IService {String NAME="default";}

默认类型等价表示是哪一项:

A.public String NAME="default";

B.public static String NAME="default";

C.public static final String NAME="default";

D.private String NAME="default";

解析:

接口当中的成员变量默认是:public static final

接口当中的成员方法默认是:public abstract

一般定义的时候不加,也是默认为以上的形式存在的

故:选择C


以下哪些方法是Object类中的方法?(多选)

A.clone()

B.toString()

C.wait()

D.finalize()

解析:

参考Object类的源码我们发现,所有方法均存在。

A:是用来进行对象的克隆

B:将对象的属性等信息,以字符串的形式输出

C:调用wait方法,当前线程进入等待状态

D:在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象。


String类OJ

字符串相加

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

示例 1:

输入:num1 = "11", num2 = "123"
输出:"134"

示例 2:

输入:num1 = "456", num2 = "77"
输出:"533"

示例 3:

输入:num1 = "0", num2 = "0"
输出:"0"

提示:

  • 1 <= num1.length, num2.length <= 104
  • num1 和num2 都只包含数字 0-9
  • num1 和num2 都不包含任何前导零

思路:

本题我们只需要对两个整数模拟「竖式加法」的过程。竖式加法就是我们平常学习生活中常用的对两个整数相加的方法,回想一下我们在纸上对两个整数相加的操作,将相同数位对齐,从低到高逐位相加,如果当前位和超过 10,则向高位进一位,我们只要将这个过程用代码写出来即可

具体实现也不复杂,我们定义两个指针 和 分别指向 num1 和 num2 的末尾,即最低位,同时定义一个变量 add 维护当前是否有进位,然后从末尾到开头逐位相加即可。当两个数字位数不同时,我们统一在指针当前下标处于负数的时候返回0,等价于对位数较短的数字进行了补零操作,这样就可以除去两个数字位数不同情况的处理,具体可以看下面的代码:

class Solution {
    public String addStrings(String num1, String num2) {
        int i = num1.length() - 1, j = num2.length() - 1, add = 0;
        StringBuffer ans = new StringBuffer();
        while (i >= 0 || j >= 0 || add != 0) {
            int x = i >= 0 ? num1.charAt(i) - '0' : 0;
            int y = j >= 0 ? num2.charAt(j) - '0' : 0;
            int result = x + y + add;
            ans.append(result % 10);
            add = result / 10;
            i--;
            j--;
        }
        // 计算完以后的答案需要翻转过来
        ans.reverse();
        return ans.toString();
    }
}

解析:


第一个只出现一次的字符

给定一个字符串 s ,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1 。

示例 1:

输入: s = "leetcode"
输出: 0

示例 2:

输入: s = "loveleetcode"
输出: 2

示例 3:

输入: s = "aabb"
输出: -1

提示:

  • 1 <= s.length <= 105
  • s 只包含小写字母
    public static int firstUniqChar(String s) {
        int[] count = new int[26];
        for (int i = 0; i < s.length(); i++) {
            count[s.charAt(i) - 'a']++;
        }
        for(int j = 0; j < s.length();j++){
            if(count[s.charAt(j) - 'a'] == 1){
                return j;
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        String str = "loveleetcode";
        int ret = firstUniqChar(str);
        System.out.println(ret);
    }

解析:


字符串最后一个单词的长度

描述

计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)

输入描述:

输入一行,代表要计算的字符串,非空,长度小于5000。

输出描述:

输出一个整数,表示输入字符串最后一个单词的长度。

示例:

输入:hello nowcoder

输出:8

说明:最后一个单词为nowcoder,长度为8

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        str.trim();//去除字符串前后的空格
        String[] tmp = str.split(" ");//将字符串按空格为分隔符,分割为字符数组
        System.out.println(tmp[tmp.length-1].length());//计算tmp 数组长度-1下标 的字符串的长度
    }

验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。

示例 1:

输入: s = "A man, a plan, a canal: Panama"

输出:true

解释:"amanaplanacanalpanama" 是回文串。

示例 2:

输入:s = "race a car"

输出:false

解释:"raceacar" 不是回文串。

示例 3:

输入:s = " "

输出:true

解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。

由于空字符串正着反着读都一样,所以是回文串。

提示:

1 <= s.length <= 2 * 105

s 仅由可打印的 ASCII 字符组成

    public static boolean isPalindrome(String s){
        s = s.toLowerCase();
        int left = 0;
        int right = s.length() - 1;
        while(left < right){
            while(left < right && !isNumberAndCharacter(s.charAt(left))) {
                left++;
            }
            while(left < right && !isNumberAndCharacter(s.charAt(right))) {
                right--;
            }
            if(s.charAt(left) == s.charAt(right)) {
                left++;
                right--;
            }else {
                return false;
            }
        }
        return true;
    }
    public static boolean isNumberAndCharacter(char ch){
        if(Character.isDigit(ch) || Character.isLetter(ch)){
            return true;
        }
        return false;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        System.out.println(isPalindrome(str));
    }

解析:


指出下列程序运行的结果()

public class Example{
    String str = new String("good");
    char[ ] ch = { 'a' , 'b' , 'c' };
    public static void main(String args[]){
        Example ex = new Example();
        ex.change(ex.str,ex.ch);
        System.out.print(ex.str + " and ");
        System.out.print(ex.ch);
    }
    public void change(String str,char ch[ ]){
        str = "test ok";
        ch[0] = 'g';
    }
}

A.good and abc

B.good and gbc

C.test ok and abc

D.test ok and gbc

解析:


下面代码将输出什么内容:() 

public class SystemUtil{
	public static boolean isAdmin(String userId){
		return userId.toLowerCase()=="admin";
	}
	public static void main(String[] args){
		System.out.println(isAdmin("Admin"));
	}
}

A.true

B.false

C.1

D.编译错误

解析:

本题主要考察的代码部分为:

return userId.toLowerCase()=="admin";

== 两边的是引用数据类型,比较的是地址是否相同,"admin"存放在常量池中,

我们查看 userId.toLowerCase() 方法的源码(JDK1.8中),发现最终返回值:return new String(形参...),并不是常量池的"admin",所以这里比较的结果就是false,选B


转换成小写字母

给你一个字符串 s ,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。

示例 1:

输入:s = "Hello"

输出:"hello"

示例 2:

输入:s = "here"

输出:"here"

示例 3:

输入:s = "LOVELY"

输出:"lovely"

解法一:利用String自带函数

class Solution {
    public String toLowerCase(String s) {
        return s.toLowerCase();
    }
}

解法二:自己实现(两种方式)

    //第一种方式
    public static String toLowerCase(String s) {
        if(s == null || s.length() == 0) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            //大写字母进行转换
            if(ch >= 'A' && ch <= 'Z') {
                sb.append((char)(ch+32));
            }else{
                //小写字母直接拼接
                sb.append(ch);
            }
        }
        return sb.toString();
    }
    
    //第二种方式
    public static String toLowerCase(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if(ch >= 65 && ch <= 90) {
                ch |= 32;
            }
            sb.append(ch);
        }
        return sb.toString();
    }

 解法三:

    //这种字符串拼接因为要创建很多新对象,所以效率极低,更推荐用StringBuffer或StringBuilder
//    public static String toLowerCase(String s) {
//        String ret = "";
//        for (int i = 0; i < s.length(); i++) {
//            char ch = s.charAt(i);
//            //判断当前字符是不是字母
//            if(Character.isLetter(ch)) {
//                //判断是不是大写字母
//                if(Character.isUpperCase(ch)) {
//                    //因为ch + 32 发生了向上转型,变为int型4字节,char型的ch装不下,所以需要强转为char型
//                    ch = (char)(ch + 32);
//                }
//            }
//            ret += ch;
//        }
//        return ret;
//    }
    public static String toLowerCase(String s) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            //判断当前字符是不是字母
            if(Character.isLetter(ch)) {
                //判断是不是大写字母
                if(Character.isUpperCase(ch)) {
                    //因为ch + 32 发生了向上转型,变为int型4字节,char型的ch装不下,所以需要强转为char型
                    ch = (char)(ch + 32);
                }
            }
            stringBuffer.append(ch);
        }
        return stringBuffer.toString();
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        System.out.println(toLowerCase(str));
    }

字符串中的单词数

统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。

请注意,你可以假定字符串里不包括任何不可打印的字符。

示例:

输入: "Hello, my name is John"

输出: 5

解释: 这里的单词是指连续的不是空格的字符,所以 "Hello," 算作 1 个单词。

以下是自己写的:

    public static int countSegments(String s) {
        String[] tmp = s.split(" ");
        int count = 0;
        for (int i = 0; i < tmp.length; i++) {
            count++;
        }
        return count;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();

        System.out.println(countSegments(str));
    }

欠缺之处:

  • 没有考虑到参数为空和字符串为空的情况
  • 没有考虑到字符串中有很多空格的情况,如右图这样:

优化后:

    public static int countSegments(String s) {
        s = s.trim();
        if(s == null || s.isEmpty()) {
            return 0;
        }
        String[] tmp = s.split(" ");
        int count = 0;
        for (int i = 0; i < tmp.length; i++) {
            if(tmp[i].isEmpty()) { //用来判断字符串中有很多空格的情况
                continue;
            }
            count++;
        }
        return count;
    }

20240529——异常的基本用法

有关下述Java代码描述正确的选项是____。

public class TestClass {

  private static void testMethod(){

    System.out.println("testMethod");

  }

  public static void main(String[] args) {

    ((TestClass)null).testMethod();

  }

}

A.编译不通过

B.编译通过,运行异常,报NullPointerException

C.编译通过,运行异常,报IllegalArgumentException

D.编译通过,运行异常,报NoSuchMethodException

E.编译通过,运行异常,报Exception

F.运行正常,输出testMethod

解析:

testMethod是静态方法,可以通过类名进行调用

将null强转为TestClass类型后,可以调用testMethod方法

(多选)下面有关JAVA异常类的描述,说法错误的是?

A. 异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception

B.非RuntimeException一般是外部错误(非Error),其必须被 try{}catch语句块所捕获

C. Error类体系描述了Java运行系统中的内部错误以及资源耗尽的情形,Error不需要捕捉

D.RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等,必须被 try{}catch语句块所捕获

解析:

B选项指的是编译时异常/受查异常,我们如果不解决他,可以用throws声明,将异常交给JVM处理,这样就可以不用被try-catch所捕获

D选项是运行时异常/非受查异常,在运行时才会报错,编译时会正常通过,不用必须try-catch捕获

实现一个简单的控制台版用户登陆程序, 程序启动提示用户输入用户名密码. 如果用户名密码出错, 使用自定义异常的方式来处理

public class UserNameException extends RuntimeException{
    public UserNameException() {
        super();
    }
    public UserNameException(String s) {
        super(s);
    }
}


public class PassWordException extends RuntimeException{
    public PassWordException() {
        super();
    }
    public PassWordException(String s) {
        super(s);
    }
}


public class Login {
    private String userName = "abc";
    private String passWord = "123";

    public void logInFo(String userName,String passWord) {
        if(!this.userName.equals(userName)) {
            throw new UserNameException("用户名错误异常!");
        }
        if(!this.passWord.equals(passWord)) {
            throw new PassWordException("密码错误异常!");
        }
        System.out.println("登录成功!");
    }
}


import java.util.Scanner;
public class Test {
    public static void main(String[] args) throws UserNameException,PassWordException{
        Login login = new Login();
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String userName = sc.nextLine();
        System.out.println("请输入密码:");
        String passWord = sc.nextLine();
        try {
            login.logInFo(userName,passWord);

        }catch(UserNameException | PassWordException e) {
            e.printStackTrace();
        } finally {

        }
    }
}



方法一:转为字符串,利用前后指针

class Solution {
    public boolean isPalindrome(int x) {
        //负数、个位是0的数(数字0除外)都不是回文
        if(x < 0 || x % 10 == 0 && x != 0) {
            return false;
        }
        //int 类型转为 String 类型,三种方法
        //String str = Integer.toString(x);
        String str = x + "";
        //String str = String.valueOf(x);

        //利用前后指针的方法分别比较前后字符
        int left = 0;
        int right = str.length() - 1;
        while(left < right) {
            if(str.charAt(left) == str.charAt(right)) {
                left++;
                right--;
            } else {
                return false;
            }
        }
        return true;
    }
}

方法二:反转整数后半部分与前半部分进行比较

tip:

1. 考虑到反转后整数溢出问题,所以只反转数字的一半,而不是反转全部

2. 所有的负数都不是回文,因为负号不会对称

3. 个位为 0 的(除了数字 0)都不是回文,因为最高位不可能为 0

//不转为字符串
class Solution {
    public boolean isPalindrome(int x) {
        if (x < 0 || x % 10 == 0 && x != 0) {
            return false;
        }
        int num = 0;

        //在整个过程中不断的在将原始数字除以10,然后给反转后的数字乘上10
        //所以当原始数字小于或等于反转后的数字时,就意味着已经处理了一半位数的数字了
        while (x > num) {
            //每次循环都把当前的 num 乘以10,再加上当前的 x%10
            num =  num * 10 + x % 10;
            x /= 10;
        }

        //当数字为奇数时,可以通过 num/10 去除中位的数字,中位数字等于它本身可忽略
        return x == num || x == num / 10;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值