让 JVM 抛出一个 OutOfMemoryError 内存溢出错误

本机内存溢出

DirectMemory容量可以通过-XX:MaxDirectMemorySize指定。

import java.lang.reflect.Field;
import sun.misc.Unsafe;

public classDirectMemoryOOM {
    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) throws IllegalArgumentException,
            IllegalAccessException {
        Field unsafeField = Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);

        while (true) {
            try {
                unsafe.allocateMemory(_1MB);
            } catch (OutOfMemoryError er) {
                System.out.println(er.toString());
                System.exit(0);
            }
        }
    }
}

// java.lang.OutOfMemoryError

为什么有时不声明 throws 也可以编译通过

RuntimeException不需要强制对其进行声明和捕获。可以认为Checked exception就是要强制程序员去处理这个异常(不管你throws多少层,终归要在某个地方catch),而Runtime exception则没有这个限制,可以自由选择是否catch

// 定义的是一个必检异常
class HexFormatException extends Exception { }

// 定义的是一个运行时异常
class BinaryFormatException extends NumberFormatException {}

NumberFormatException extends IllegalArgumentException

IllegalArgumentException extends RuntimeException

根据凸多边形顶点坐标来计算面积的算法与实现

把凸多边形划分成若干个三角形,取多边形的一个顶点为三角形共同顶点

double x0 = x.get(0);
double y0 = y.get(0);

三角形个数 = 坐标对数 – 2

// 每个三角形的三条边 i从0开始
double s1 = Math.sqrt(Math.pow(x0 - x.get(i + 1), 2) + Math.pow(y0 - y.get(i + 1), 2));
double s2 = Math.sqrt(Math.pow(x0 - x.get(i + 2), 2) + Math.pow(y0 - y.get(i + 2), 2));
double s3 = Math.sqrt(Math.pow(x.get(i + 1) - x.get(i + 2), 2) + Math.pow(y.get(i + 1) - y.get(i + 2), 2));
// 每个三角形的面积
double s = (s1 + s2 + s3) / 2;
double area = Math.pow((s * (s - s1) * (s - s2) * (s - s3)), 1.0 / 2);

Java实现代码等待一段时间后执行

方法一:线程睡眠,根据系统计时器和调度程序的精度和准确性,使当前正在执行的线程进入休眠状态(暂时停止执行)达指定的毫秒数。 该线程不会失去任何监视器的所有权,参数单位是毫秒

Thread.sleep(3000); // 毫秒

// 特殊情况
Thread.currentThread().sleep(1000); // 毫秒

方法二:java.util.concurrent.TimeUnit 类中的 sleep() 方法,底层调用的也是线程睡眠

import java.util.concurrent.TimeUnit;

TimeUnit.DAYS.sleep(1); // 天
TimeUnit.HOURS.sleep(1); // 小时
TimeUnit.MINUTES.sleep(1); // 分
TimeUnit.SECONDS.sleep(1); // 秒
TimeUnit.MILLISECONDS.sleep(1000); // 毫秒
TimeUnit.MICROSECONDS.sleep(1000); // 微妙
TimeUnit.NANOSECONDS.sleep(1000); // 纳秒

报未处理异常: java.lang.InterruptedException?
使用 try/catch 环绕

try{
    TimeUnit.MINUTES.sleep(1);
} catch (InterruptedException e) {
    e.printStackTrace();
}

微信无法登录,扫码后报错:java.lang.NumberFormatException:null

原因:微信需加JVM运行参数

找到你的IDE所在的安装目录下的bin文件夹,打开,找到你的exe运行参数文件,如(idea64.exe.vmoptions,studio64.exe.vmoptions)使用编辑器打开,在最后一行添加

-Djsse.enableSNIExtension=false
// 保存后重启IDE

也可以通过exe快捷方式添加参数,如快捷方式目标指向:

E:\Android\eclipse\eclipse.exe -nl=en -Djsse.enableSNIExtension=false

这种方式要求exe所在的路径不能带空格

*Java系统属性的修改通常只能用于本次运行

将Java系统属性Djsse.enableSNIExtension设置为false,$java -Djsse.enableSNIExtension=false
尝试运行时只输出帮助信息?解决方法:

$java -Djsse.enableSNIExtension=false MainClass
$java -Djsse.enableSNIExtension=false -jar foobar.jar

String类valueOf(int i)方法的实现

Java 库 String 类的 valueOf 方法大致可以分为三种:

  • String.valueOf(Object)
  • String.valueOf(char[])
  • String.valueOf(基本数据类型)


String.valueOf(int i)源码:

public static String valueOf(int i) {
        return Integer.toString(i);
}


Integer.toString(int i)源码:

public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        getChars(i, size, buf);
        return new String(buf, true);
}


Integer.getChars(int i, int index, char[] buf)的源码:

static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        if (i < 0) {
            sign = '-';
            i = -i;
        }

        // Generate two digits per iteration
        while (i >= 65536) {
            q = i / 100;
        // really: r = i - (q * 100);
            r = i - ((q << 6) + (q << 5) + (q << 2));
            i = q;
            buf [--charPos] = DigitOnes[r];
            buf [--charPos] = DigitTens[r];
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        for (;;) {
            q = (i * 52429) >>> (16+3);
            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
            buf [--charPos] = digits [r];
            i = q;
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
    }

其他方式实现MyString1 valueOf(int i)

public static MyString1 valueOf(int i) {
        int n;
        char[] temp;
        int count;

        if (i <= Character.MAX_VALUE)
            return new MyString1(Character.toChars(i));
        else {
            n = i % Character.MAX_VALUE;
            count = i / Character.MAX_VALUE;
            temp = new char[count + 1];
            temp[0] = (char) n;
            for (int j = 1; j <= count; j++)
                temp[j] = Character.MAX_VALUE;
            return new MyString1(temp);
        }
    }

第七章第五题(打印不同的教)(Print distinct numbers) – 编程练习题答案

编写一个程序,读人10 个数并且显示互不相同的数(即一个数出现多次,但仅显示一次)。(提示,读人一个数,如果它是一个新数,则将它存储在数组中。如果该数已经在数组中,则忽略它。)输入之后,数组包含的都是不同的数。下面是这个程序的运行示例:

Write a program that reads in ten numbers and displays
the number of distinct numbers and the distinct numbers separated by exactly one
space (i.e., if a number appears multiple times, it is displayed only once). (Hint:
Read a number and store it to an array if it is new. If the number is already in the
array, ignore it.) After the input, the array contains the distinct numbers.

下面是参考答案代码:

// 缺陷版本
import java.util.Arrays;
import java.util.Scanner;

public class Ans7_5_page236 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter ten numbers: ");
        int[] numberList = new int[10];
        // int[] distinctList = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
        int[] distinctList = new int[10];
        Arrays.fill(distinctList,-1);

        for (int i = 0; i < 10; i++)
            numberList[i] = input.nextInt();

        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10;j++) {
                if (i == numberList[j])
                    distinctList[i] = numberList[j];
            }
        }

        int count = 0;
        for (int i = 0; i < 10; i++) {
            if (distinctList[i] != -1)
                count++;
        }
        System.out.print("The number of distinct number is " + count+
                "\nThe distinct numbers are: ");

        for (int i = 0; i < 10; i++) {
            if (distinctList[i] != -1) {
                System.out.print(distinctList[i] + " ");
            }
        }
    }
}

// 完善版本
import java.util.Arrays;
import java.util.Scanner;

public class Ans7_5_page236 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter ten numbers: ");
        int[] numberList = new int[10];

        int maxInt = -99;
        for (int i = 0; i < 10; i++) {
            numberList[i] = input.nextInt();
            if (numberList[i] > maxInt)
                maxInt = numberList[i];
        }

        int[] distinctList = new int[maxInt];
        Arrays.fill(distinctList, -99);

        int disNum = 0;
        for (int i = 0; i < maxInt; i++) {
            for (int j = 0; j < 10; j++) {
                if (i == numberList[j])
                    distinctList[i] = numberList[j];
                else if (distinctList[i] != -99)
                    disNum = distinctList[i];
            }
        }

        int count = 0;
        for (int i = 0; i < maxInt; i++) {
            if (distinctList[i] != -99) {
                count++;
            }
        }
        System.out.print("The number of distinct number is " + disNum +
                "\nThe distinct numbers are: ");

        for (int i = 0; i < maxInt; i++) {
            if (distinctList[i] != -99) {
                System.out.print(distinctList[i] + " ");
            }
        }
        System.out.print(maxInt);
    }
}

//        Enter ten numbers: 1 2 3 2 1 6 3 4 5 2
//        The number of distinct number is 5
//        The distinct numbers are: 1 2 3 4 5 6

//        Enter ten numbers: 11 22 33 22 11 66 33 44 55 67
//        The number of distinct number is 66
//        The distinct numbers are: 11 22 33 44 55 66 67

适用Java语言程序设计与数据结构(基础篇)(原书第11版)Java语言程序设计(基础篇)(原书第10/11版)

发布在博客:(https://cn.fankuiba.com)

第七章第四题(分析成绩)(Analyze scores) – 编程练习题答案

编写一个程序,读人个数不确定的考试分数,并且判断有多少个分数是大于或等于平均分,多少个分数是低于平均分的。输人一个负数表示输入的结束。假设最高分为100。

Write a program that reads an unspecified number of scores and
determines how many scores are above or equal to the average and how many
scores are below the average. Enter a negative number to signify the end of the
input. Assume that the maximum number of scores is 100.

下面是参考答案代码:

// https://cn.fankuiba.com
import java.util.Scanner;

public class Ans7_4_page236 {
    public static void main(String[] args) {
        double[] scoreList = new double[100];
        Scanner input = new Scanner(System.in);
        System.out.print("Enter scores: (negative number signifies end): ");
        int count= 0;double score;
        do {
            score = input.nextDouble();
            scoreList[count] = score;
            count++;
        }while (score >= 0);

        double average,sum = 0;
        for (int i = 0; i < count-1; i++)
            sum += scoreList[i];

        average = sum / (count - 1);
        System.out.println("Average of scores: "+average);
        int minAverge = 0;
        int maxAverge = 0;
        for (int i = 0; i < count-1; i++) {
            if (scoreList[i] >= average)
                minAverge++;
            else
                maxAverge++;
        }
        System.out.println("Number of scores above or equal to average: " +minAverge+
                "\n"+"Number of scores below average: "+(maxAverge));
    }
}

适用Java语言程序设计与数据结构(基础篇)(原书第11版)Java语言程序设计(基础篇)(原书第10/11版)

发布在博客:(https://cn.fankuiba.com)

第七章第三题(计算数字的出现次数)(Count occurrence of numbers) – 编程练习题答案

编写程序,读取在1到100 之间的整数,然后计算每个数出现的次数。假定输入是以0 结束的。

下面是这个程序的一个运行示例:

Write a program that reads the integers between 1and 100 and counts the occurrences of each. Assume the input ends with 0.Note that if a number occurs more than one time, the plural word “times” is used

in the output.

Enter the integers between 1 and 100: 2 5 6 5 4 3 23 43 2 0
2 occurs 2 times
3 occurs 1 time
4 occurs 1 time
5 occurs 2 times
6 occurs 1 time
23 occurs 1 time
43 occurs 1 time

下面是参考答案代码:

// https://cn.fankuiba.com
import java.util.Scanner;

public class Ans7_3_page236 {
    public static void main(String[] args) {
        int[] number = new int [101];
        Scanner input = new Scanner(System.in);
        int num;
        System.out.print("Enter the integers between 1 and 100: ");
        do {
            num = input.nextInt();
            number[num] = number[num] + 1;
        }
        while (num != 0);
        for (int i = 1; i < number.length; i++) {
            if (number[i] == 1) {
                System.out.println(i + " occurs " + number[i] + " time");
            }else if (number[i] > 1)
                System.out.println(i + " occurs " + number[i] + " times");
        }
    }
}

适用Java语言程序设计与数据结构(基础篇)(原书第11版)Java语言程序设计(基础篇)(原书第10/11版)

发布在博客:(https://cn.fankuiba.com)

第七章第二题(倒置输入的数)(Reverse the numbers entered) – 编程练习题答案

编写程序,读取10 个整数,然后按照和读入顺序相反的顺序将它们显示出来。

Write a program that reads ten integers and displays
them in the reverse of the order in which they were read.

// https://cn.fankuiba.com
import java.util.Scanner;

public class Ans7_2_page236 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter 10 integers: ");
        int[] number = new int[10];
        for (int i = 0; i < 10; i++) {
            number[i] = input.nextInt();
        }
        for (int i = 9; i >= 0; i--)
            System.out.print(number[i]+" ");
    }
}

适用Java语言程序设计与数据结构(基础篇)(原书第11版)Java语言程序设计(基础篇)(原书第10/11版)

发布在博客:(https://cn.fankuiba.com)