JAVA上机实验笔记

发布于 / 笔迹 / 12 条评论

JAVA上机实验习题解答,不保证一定是正确的,仅供参考。若文中存在错误,请及时指出。

目录

  1. 实验一:角谷猜想
  2. 实验二:计算e^x
  3. 实验三:复数类
  4. 实验四:圆类
  5. 实验五:整型集合类
  6. 实验六:判断身份证
  7. 实验七:文本符号化
  8. 实验八:读取文本内容并逆序输出
  9. 实验九:两个线程分别计算素数和
  10. 实验十:模拟屏幕保护程序
  11. 实验十一:JAVA操作数据库实现增查

实验一:角谷猜想

分析

没什么好说的,直接写就行了。

代码

  • JAVA应用程序实现
// 直接证明(3到30000以内的所有数都符合,所以都会输出)

public class Main
{
    public static boolean JiaoGu(int n)
    {
        while (n != 1) // 如果不符合角谷猜想则会陷入死循环
        {
            if (n % 2 == 0)
                n /= 2;
            else
                n = 3 * n + 1;
        }
        return true; // 符合则会返回真
    }

    public static void main(String[] args)
    {
        for (int i = 3; i <= 30000; ++i) // 从3到30000都验证一遍
        {
            if (JiaoGu(i)) // 符合则会输出
                System.out.print(i + " ");
            if (i % 30 == 0) // 换行输出
                System.out.println();
        }
    }
}

// 手动输入(输入一个判断一个)

import java.util.Scanner;

public class Main
{
    public static boolean JiaoGu(int n)
    {
        while (n != 1)
        {
            if (n % 2 == 0)
            {
                System.out.println(n + " / 2 = " + n/2);
                n /= 2;
            }
            else
            {
                System.out.println( "3 * " + n + " + 1 = "  + (3*n+1));
                n = 3 * n + 1;
            }
        }
//        System.out.println(n);
        return true;
    }

    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        System.out.print("请输入3~30000以内的数:");
        int x = cin.nextInt();
        if (JiaoGu(x))
            System.out.println(x + " 符合角谷猜想。");
        else
            System.out.println(x + " 不符合角谷猜想。");
    }
}

/*
请输入3~30000以内的数:11
3 * 11 + 1 = 34
34 / 2 = 17
3 * 17 + 1 = 52
52 / 2 = 26
26 / 2 = 13
3 * 13 + 1 = 40
40 / 2 = 20
20 / 2 = 10
10 / 2 = 5
3 * 5 + 1 = 16
16 / 2 = 8
8 / 2 = 4
4 / 2 = 2
2 / 2 = 1
11符合角谷猜想
*/

  • JAVA小应用程序实现
// 输入后判断,控制台输出数的变化过程

import java.awt.*;
import java.applet.*;

public class Main extends Applet
{
    Label info;
    TextField input, output;
    int num, nums;
    Graphics g;

    public void init( )
    {
        info = new Label("请输入3~30000以内的数");
        input = new TextField(10);
//      output = new TextField(10);
        add(info);
        add(input);
//      add(output);
    }

    public boolean action(Event e , Object o)
    {
        if (e.target==input)
        {
            num=Integer.parseInt(input.getText( ));
            nums = num;
            int xpos = 20, ypos = 20;
            System.out.println("控制台" + num + "的变化过程如下:");
            while (num != 1)
            {
                if (num % 2 == 0)
                {
                    showStatus(num + " / 2 = " + num/2);
                    System.out.println(num + " / 2 = " + num/2);
//                  g.drawString(num + " / 2 = " + num/2, xpos, ypos); // error
//                  ypos += 20;
                    num /= 2;
                }
                else
                {
                    showStatus("3 * " + num + " + 1 = "  + (3*num+1));
                    System.out.println( "3 * " + num + " + 1 = "  + (3*num+1));
//                  g.drawString("3 * " + num + " + 1 = "  + (3*num+1), xpos, ypos); // error
//                  ypos += 20;
                    num = 3*num + 1;
                }
            }
            showStatus(nums + " 符合角谷猜想, 最后的值为:" + num);
        }
        return true;
    }
} 


实验二:计算e^x

分析

没什么好讲的,计算一下阶乘就行(注意参数问题)。

代码

  • 应用程序版
import java.util.Scanner;
import java.math.*;

public class EandX
{
    public static int fac(int n)
    {
        int mul = 1;
        for (int i = 2; i <= n; ++i)
            mul *= i;
        System.out.println(mul);
        return mul;
    }

    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        int x, n;
        x = cin.nextInt();
        n = cin.nextInt();
        double sum = 1.0;
        for (int i = 1; i <= n; ++i)
            sum += Math.pow(x*1.0, i*1.0) / fac(i)*1.0;
//        System.out.println(sum);
        System.out.println(String.format("%.10f", sum)); // 保留10位小数
    }
}
  • 小程序版本
import java.awt.*;
import java.applet.*;

public class EandX extends Applet
{
    Label info1, info2;
    TextField input1, input2;
    int n, x;
    double sum;

    public void init( )
    {
        info1 = new Label("请输入n:");
        input1 = new TextField(20);
        info2 = new Label("请输入x:");
        input2 = new TextField(20);

        add(info1);
        add(input1);
        add(info2);
        add(input2);
    }

    public int fac(int n)
    {
        int mul = 1;
        for (int i = 2; i <= n; ++i)
            mul *= i;
        System.out.println(mul);
        return mul;
    }

    public boolean action(Event e , Object o)
    {
        sum = 1.0;
        if (e.target == input1 || e.target == input2)
        {
            n = Integer.parseInt(input1.getText( ));
            x = Integer.parseInt(input2.getText( ));
            for (int i = 1; i <= n; ++i)
                sum += Math.pow(x*1.0, i*1.0) / fac(i)*1.0;
            showStatus("e的" + x + "次方的值为:" + sum);
        }
        return true;
    }
}


实验三:复数类

分析

没什么好讲的,类的简单实现。

代码

import java.util.*;

class complex
{
    int realPart, imagPart;
    complex(int _real, int _imag)
    {
        realPart = _real;
        imagPart = _imag;
    }
    void add(complex other)
    {
        this.realPart += other.realPart;
        this.imagPart += other.imagPart;
    }
    void minus(complex other)
    {
        this.realPart -= other.realPart;
        this.imagPart -= other.imagPart;
    }
}

public class Main
{
    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        int a1, b1, a2, b2;
        System.out.print("Please enter the realPart and imagPart of the first complex: ");
        a1 = cin.nextInt();
        b1 = cin.nextInt();
        System.out.print("Please enter the realPart and imagPart of the second complex: ");
        a2 = cin.nextInt();
        b2 = cin.nextInt();
        complex a = new complex(a1, b1);
        complex b = new complex(a2, b2);
        a.add(b);
        if (a.realPart == a1 + a2 && a.imagPart == b1 + b2)
            System.out.println("The result of add is right, they are: " + a.realPart + " " + a.imagPart);
        else
            System.out.println("Error, please check your program.");
        a1 = a1 + a2;
        b1 = b1 + b2;
        a.minus(b);
        if (a.realPart == a1 - a2 && a.imagPart == b1 - b2)
            System.out.println("The result of add is right, they are: " + a.realPart + " " + a.imagPart);
        else
            System.out.println("Error, please check your program.");
    }
}
/*
Please enter the realPart and imagPart of the first complex: 2 3
Please enter the realPart and imagPart of the second complex: 4 5
The result of add is right, they are: 6 8
The result of add is right, they are: 2 3
*/


实验四:圆类

分析

依然没什么好讲的,类的简单实现。

代码

import java.util.*;

class circle
{
    int radius;
    circle (int r)
    {
        radius = r;
    }
    double circum()
    {
        return 2 * Math.PI * radius;
    }
    double area()
    {
        return Math.PI * radius * radius;
    }
}

public class Main
{
    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        int r;
        System.out.print("PLease enter the radius of the circle: ");
        r = cin.nextInt();
        if (r < 0)
            System.out.println("Error, the radius of the circle can't be a negative number.");
        else
        {
            circle c = new circle(r);
            double circum = c.circum();
            double area = c.area();
            System.out.println("The circumference of the circle is : " + String.format("%.4f", circum));
            System.out.println("THe area of the circle is : " + String.format("%.4f", area));
        }
    }
}
/*
PLease enter the radius of the circle: 2
The circumference of the circle is : 12.5664
THe area of the circle is : 12.5664
*/


实验五:整型集合类

分析

① 使用boolen数组来对集合中的元素进行标记判断集合是否相等
② 交集判断可以使用boolen数组或者双重循环遍历
③ 并集使用boolen数组
④ 插入只需后移
⑤ 删除只需前移

代码

import java.util.*;
import java.math.*;
import java.io.*;

class integerSet
{
    Scanner cin = new Scanner(System.in);

    int n; // 长度
    int array[] = new int[20]; // 基本元素
    int Sarray[] = new int[20]; // 交集
    int Uarray[] = new int[20]; // 并集

    void init() // 初始化
    {
        System.out.print("Please enter the length of the sets: ");
        n = cin.nextInt();
        System.out.print("Now you can enter their values individually: ");
        for (int i = 0; i < n; ++i)
            array[i] = cin.nextInt();
    }

    void print() // 输出
    {
        System.out.print("The elements in the sets are: ");
        for (int i = 0; i < n; ++i)
            System.out.print(array[i] + " ");
        System.out.println();
    }

    boolean isEqual(integerSet other) // 是否相等
    {
        if (this.n != other.n)
            return false;
        boolean tmp1[] = new boolean[100];
        boolean tmp2[] = new boolean[100];
        for (int i = 0; i < this.n; ++i)
        {
            tmp1[this.array[i]] = true;
            tmp2[other.array[i]] = true;
        }
        for (int i = 0; i < 100; ++i)
        {
            if (tmp1[i] != tmp2[i])
                return false;
        }
        return true;
    }

    void Union(integerSet other) // 并集
    {
        boolean tmp[] = new boolean[100];
        for (int i = 0; i < this.n; ++i)
            tmp[this.array[i]] = true;
        for (int j = 0; j < other.n; ++j)
            tmp[other.array[j]] = true;
        int k = 0;
        for (int i = 0; i < 100; ++i)
        {
            if (tmp[i])
                Uarray[k++] = i;
        }
        System.out.print("The elements in the union of these two sets are: ");
        for (int i = 0; i < k; ++i)
            System.out.print(Uarray[i] + " ");
        System.out.println();
    }

    void Inter(integerSet other) // 交集
    {
        boolean tmp[] = new boolean[100];
        for (int i = 0; i < this.n; ++i)
        {
            for (int j = 0; j < other.n; ++j)
            {
                if (this.array[i] == other.array[j])
                    tmp[this.array[i]] = true;
            }
        }
        int k = 0;
        for (int i = 0; i < 100; ++i)
        {
            if (tmp[i])
                Sarray[k++] = i;
        }
        System.out.print("The elements in the intersection of these two sets are: ");
        for (int i = 0; i < k; ++i)
            System.out.print(Sarray[i] + " ");
        System.out.println();
    }

    void insert() // 插入
    {
        int pos, value;
        System.out.print("Please enter the position of the inserted element: ");
        pos = cin.nextInt();
        System.out.print("Please enter the vlaue of the inserted element: ");
        value = cin.nextInt();
        for (int i = n; i > pos; --i)
            array[i] = array[i-1];
        array[pos] = value;
        ++n;
        this.print();
    }

    void remove() // 删除
    {
        int pos;
        System.out.print("Please enter the position of the deleted element: ");
        pos = cin.nextInt();
        for (int i = pos; i < n - 1; ++i)
            array[i] = array[i+1];
        --n;
        this.print();
    }
}

public class Main
{
    public static void main(String []args)
    {
        integerSet a = new integerSet();
        integerSet b = new integerSet();
        a.init();
        b.init();
        if (a.isEqual(b))
            System.out.println("The two sets are equal.");
        else
            System.out.println("The two sets are not equal.");
        a.Union(b); // 操作
        a.Inter(b);
        a.insert();
        a.remove();
    }
}

/*
Please enter the length of the sets: 7
Now you can enter their values individually: 1 2 3 4 5 6 7
Please enter the length of the sets: 8
Now you can enter their values individually: 2 3 5 7 9 11 13 15
The two sets are not equal.
The elements in the union of these two sets are: 1 2 3 4 5 6 7 9 11 13 15 
The elements in the intersection of these two sets are: 2 3 5 7 
Please enter the position of the inserted element: 1
Please enter the vlaue of the inserted element: 2018
The elements in the sets are: 1 2018 2 3 4 5 6 7 
Please enter the position of the deleted element: 1
The elements in the sets are: 1 2 3 4 5 6 7 
*/

说明

我的插入和删除都是从0位置开始的,要从1位置开始的话,只需将输入的位置pos–就行,然后我把插入都删除方法都在集合类中完成,主类中直接调用,判断是否相等的话我没有完全在集合类中进行,输出在主类中。本题数据量小可以使用标记数组和双重循环,不用考虑别的问题。


实验六:判断身份证

一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:
首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值Z;最后按照以下关系对应Z值与校验码M的值:
Z:0 1 2 3 4 5 6 7 8 9 10
M:1 0 X 9 8 7 6 5 4 3 2
现在给定一些身份证号码,请你验证校验码的有效性。

分析

没什么好讲的,将计算得到的结果取模后比对一下就行。

代码

import java.util.*;
import java.math.*;
import java.io.*;

public class Main
{

    static int a[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    static String M = "10X98765432";

    static boolean IsValid(String s) // 判断是否符合校验
    {
        int sum = 0;
        int length = s.length();
        for (int i = 0; i < length - 1; ++i)
            sum += (s.charAt(i) - '0') * a[i];
        if (M.charAt(sum % 11) == s.charAt(length - 1))
            return true;
        return false;
    }

    static boolean Isnum(String s) // 判断前十七位是否为数字
    {
        int length = s.length();
        for (int i = 0; i < length - 1; ++i)
            if (!Character.isDigit(s.charAt(i)))
                return false;
        return true;
    }

    public static void main(String []args)
    {
        Scanner cin = new Scanner(System.in);
        System.out.print("请输入查询的身份证号:");
        String s = cin.next();
        if (IsValid(s) && Isnum(s))
            System.out.println("该身份证号合法");
        else
            System.out.println("该身份证号非法");
    }
}

说明

可以直接分别输入17位数字,用数组存储,比较简单,我用的是字符串,判断的时候稍微处理一下就行。


实验七:文本符号化

分析

“文本符号化”看起来好像很高级的样子,其实就是对文本进行拆分,使用StringTokenizer类的几个方法就行,逆序输出再处理一下。

代码

import java.util.*;

public class Main
{
    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        System.out.println("Please enter a line of text: ");
        String s = cin.nextLine();
        StringTokenizer str = new StringTokenizer(s);
        int count = str.countTokens();
        String ans[] = new String[count];
        for (int i = 0; i < count; i++)
            ans[i] = str.nextToken();
        System.out.println("The text of the output is: ");
        for (int i = count - 1; i >= 0; --i)
            System.out.print(ans[i] + " ");
        System.out.println();
    }
}

/*
Please enter a line of text:
JAVA is the best language
The text of the output is:
language best the is JAVA
*/

如果我们使用逗号,来分割的话,那么效果会是这样的:

Please enter a line of text: 
Hello, I am taifu, what's your name, can you speak Chinese, oh, I know, thank you
The text of the output is: 
 thank you  I know  oh  can you speak Chinese  what's your name  I am taifu Hello 

只需要把StringTokenizer str = new StringTokenizer(s);替换成StringTokenizer str = new StringTokenizer(s, "r");

说明

StringTokenizer是字符串分隔解析类型,属于:java.util包

1.StringTokenizer的构造函数

  • StringTokenizer(String str):构造一个用来解析str的StringTokenizer对象。java默认的分隔符是“空格”、“制表符(‘\t’)”、“换行符(‘\n’)”、“回车符(‘\r’)”。
  • StringTokenizer(String str,String delim):构造一个用来解析str的StringTokenizer对象,并提供一个指定的分隔符。
  • StringTokenizer(String str,String delim,boolean returnDelims):构造一个用来解析str的StringTokenizer对象,并提供一个指定的分隔符,同时,指定是否返回分隔符。

2.StringTokenizer的一些常用方法

所有方法均为public,书写格式:[修饰符] <返回类型><方法名([参数列表])>

  • int countTokens():返回nextToken方法被调用的次数。
  • boolean hasMoreTokens():返回是否还有分隔符。
  • boolean hasMoreElements():返回是否还有分隔符。
  • String nextToken():返回从当前位置到下一个分隔符的字符串。
  • Object nextElement():返回从当前位置到下一个分隔符的字符串。
  • String nextToken(String delim):与4类似,以指定的分隔符返回

说明部分来源于:Java中的StringTokenizer类的使用方法


实验八:读取文本内容并逆序输出

代码

import java.io.*;

class File
{
    String str = "";
    String strs[] = new String[500];
    int k = 0;
    void readFlie() throws Exception // 采用throws指明异常类型
    {
        FileInputStream fin = null;
        InputStreamReader in = null;
        BufferedReader br = null;
        try
        {
            fin = new FileInputStream("/home/taifu/JAVA/Study/src/document.txt"); // 读入文件 字节流
            in = new InputStreamReader(fin, "UTF-8"); // 字节流输出为字符流
            br = new BufferedReader(in);  // 缓冲方式文本读取,readLine读取一个文本,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取
            while ((str = br.readLine()) != null) // 按行读入
                strs[k++] = str; // 存入二维数组
//              strs[k++] = str + "\n";
        }
        catch (FileNotFoundException e)
        {
            System.out.println("File not found" + e);
            throw e;
        }
        finally
        {
            fin.close(); // 关闭流
            in.close();
            br.close();
        }
    }
    void showFile()
    {
        System.out.println("The first way: ");
        for (int i = this.k - 1; i >= 0; --i)
            System.out.println(strs[i]);
        System.out.println();
    }
    void showFiles()
    {
        System.out.println("The second way: ");
        for (int i = this.k - 1; i >= 0; --i)
        {
            for (int j = strs[i].length() - 1; j >= 0; --j)
                System.out.print(strs[i].charAt(j));
            System.out.println();
        }
        System.out.println();
    }
    void showFiless()
    {
        System.out.println("The third way: ");
        for (int i = this.k - 1; i >= 0; --i)
            for (int j = strs[i].length() - 1; j >= 0; --j)
                System.out.print(strs[i].charAt(j));
        System.out.println();
    }
}

public class Main
{
    public static void main(String[] args)
    {
        File file = new File();
        try
        {
            file.readFlie();
            file.showFile();
            file.showFiles();
            file.showFiless();
        }
        catch (Exception e)
        {
            System.out.println("File not found: " + e);
            e.printStackTrace();
        }
    }
}
  • 文本document.txt内容
If I should meet thee
After long years
How should I greet thee?
With silence and tears
  • 输出结果
The first way
With silence and tears
How should I greet thee?
After long years
If I should meet thee

The second way
sraet dna ecnelis htiW
?eeht teerg I dluohs woH
sraey gnol retfA
eeht teem dluohs I fI

The third way
sraet dna ecnelis htiW?eeht teerg I dluohs woHsraey gnol retfAeeht teem dluohs I fI

说明

涉及的知识还是挺多的,读取文件分别使用了FileInputStreamInputStreamReaderBufferedReader类,得到一个二维字符串数组,至于逆序输出的话很好办。

  • InputStream : 是所有字节输入流的超类,一般使用它的子类:FileInputStream等,它能输出字节流;
  • InputStreamReader : 是字节流与字符流之间的桥梁,能将字节流输出为字符流,并且能为字节流指定字符集,可输出一个个的字符;
  • BufferedReader : 提供通用的缓冲方式文本读取,readLine读取一个文本行, 从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
  • 在读取网络数据流的时候,可以通过先用InputStream获取字节流、InputStreamReader将字节流转化成字符流、BufferedReader将字符流以缓存形式输出的方式来快速获取网络数据流。

throw与throws的比较

  • throws出现在方法函数头;而throw出现在函数体。
  • throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。
  • 两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

推荐阅读


实验九:两个线程分别计算素数和

分析

没什么好说的,直接写就行,当然也有可能我做错了。

代码

  • 版本一
class ThreadOne extends Thread
{
    int sum = 0;
    boolean isPrime(int n) // 判断一个数是否是素数
    {
        for (int i = 2; i <= n/2; ++i)
            if (n % i == 0)
                return false;
        return true;
    }
    public void run() // 计算素数和
    {
        for (int i = 10; i <= 20; ++i)
            if (isPrime(i))
                sum += i;
        System.out.println("10 到 20 " + "之间的素数和是:" + sum);
    }
}

class ThreadTwo extends Thread
{
    int sum = 0;
    boolean isPrime(int n) // 判断一个数是否是素数
    {
        for (int i = 2; i <= n/2; ++i)
            if (n % i == 0)
                return false;
        return true;
    }
    public void run() // 计算素数和
    {
        for (int i = 1000; i <= 2000; ++i)
            if (isPrime(i))
                sum += i;
        System.out.println("1000 到 2000 " + "之间的素数和是:" + sum);
    }
}

public class Main
{
    public static void main(String[] args)
    {
        ThreadOne t1 = new ThreadOne(); // 线程一
        ThreadTwo t2 = new ThreadTwo(); // 线程二
        t1.start();
        t2.start();
    }
}
/*
10 到 20 之间的素数和是:60
1000 到 2000 之间的素数和是:200923
*/

  • 版本二
class Thread_Prime extends Thread
{
    int a, b;
    int sum = 0;
    Thread_Prime(int _a, int _b) // 构造函数
    {
        a = _a;
        b = _b;
    }
    boolean isPrime(int n) // 判断一个数是否是素数
    {
        for (int i = 2; i <= n/2; ++i)
            if (n % i == 0)
                return false;
        return true;
    }
    public void run() // 计算素数和
    {
        for (int i = a; i <= b; ++i)
            if (isPrime(i))
                sum += i;
        System.out.println(a + " 到 " + b + " 之间的素数和是:" + sum);
    }
}

public class Main
{
    public static void main(String[] args)
    {
        // 当然这里的参数可以自定义输入,我嫌麻烦就懒得加了
        Thread_Prime t1 = new Thread_Prime(10, 20);
        Thread_Prime t2 = new Thread_Prime(1000, 2000);
        t1.start();
        t2.start();
    }
}
/*
10 到 20 之间的素数和是:60
1000 到 2000 之间的素数和是:200923
*/

说明

程序中t1和t2的执行顺序不定。

补充

多线程的执行本身就是多个线程的交换执行,并非同时执行,执行的优先级只是他执行的概率。
例如原本优先级一样,那么两个线程的执行的概率都为50%。现在我们提高其中一个,那么一个为60%的概率抢到进入CPU执行的机会,另一个是依旧是40%。执行完一次之后又要重新抢占CPU。但是40%概率进入的线程也有可能抢到,虽然概率低了点,但总会有他执行的机会,万一次次都抽中40%的概率呢?所以你要正确理解线程和线程之间的优先级。
优先级高的线程并不一定比优先级低的线程执行的机会高,只是执行的机率高;默认一个线程的优先级和创建他的线程优先级相同。
——来源于:传送门


实验十:模拟屏幕保护程序

分析

没什么好说的,使用JAVA小程序,调用g.setColor()g.drawLine()方法即可完成,注意一下颜色的随机数处理。

代码

// 2018年6月18日 更新,完善功能,修复bug
import java.applet.*;
import java.awt.*;

public class Main extends Applet implements Runnable
{
    Thread animator;
    int width = 800, height = 600;

    public void start() 
    {
        setSize(width, height); // 设置初始布局
        animator = new Thread(this);
        animator.start();
    }

    public void run()
    {
        while (Thread.currentThread() != null)
            repaint();
    }

    public void stop()
    {
        animator = null;
    }

    public void paint(Graphics g)
    {
        int x1, x2, y1, y2, R, G, B;
        Color color;
        for (int i = 0; i < 100; ++i)
        {
            x1 = (int)(Math.random() * width); // 随机位置
            y1 = (int)(Math.random() * height);
            x2 = (int)(Math.random() * width);
            y2 = (int)(Math.random() * height);
            R = (int)(Math.random() * 256); // 随机颜色
            G = (int)(Math.random() * 256);
            B = (int)(Math.random() * 256);
            color = new Color(R, G, B);
            g.setColor(color); // 设置颜色
            g.drawLine(x1, y1, x2, y2); // 画线
            try // 使效果明显,休眠10ms
            {
                Thread.sleep(10);
            }
            catch (InterruptedException ex) 
            {
                System.out.println(ex.toString());// TODO: handle exception
            }
        }
        try 
        {
            Thread.sleep(100); // 画完100根线后,休眠100ms
            g.clearRect(0, 0, width, height); // 清除屏幕
        }
        catch (InterruptedException ex) 
        {
            System.out.println(ex.toString());// TODO: handle exception
        }
    }
}

说明

g.clearRect()为采用当前背景色清除矩形区域,若在程序中循环结束后使用后则无法看见效果,而repaint()为清除画面并强制小程序重新输出。

在这个小程序中是画线,其实画圆画矩形什么的都是可以的,调用对应的方法就行。

最开始调用start()方法,然后执行run()方法,并在run()中调用paint(),开始循环画线。

演示


实验十一:JAVA操作数据库实现增查

分析

这题的关键是什么呢?关键是能连接上数据库,增查操作的SQL语句还是比较简单的,毕竟原来学过数据库。但是在使用JDBC-ODBC桥接驱动程序会遇到各种各样的问题,所以这是难点。

使用自己电脑配置好数据库后使用eclipse连接时报错,基本上原因就是jdk版本问题,然后重新下载jdk比如1.7版本的就可以正常连接了,但是,注意,下载的jdk版本最好是32位的,不然又会遇见新的问题。 然后新下载的jdk也不需要配置环境变量,在eclipse修改一下jdk版本就行。

  • 原始数据库

  • 增加记录后的数据库

代码

  • 增加五条记录
import java.sql.*;
import java.util.*;

public class Main
{
    public static void main(String args[])
    {
        try
        {
            // 加载JDBC-ODBC桥接驱动程序
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        }
        catch (ClassNotFoundException ce)   //当无法载入JDBC驱动程序时捕捉异常
        {
            System.out.println("SQLException:" + ce.getMessage());
        }

        try
        {
            //连接数据源myDB,汉字编码采用GBK,否则显示汉字时可能会出现乱码
            Properties prop = new Properties();
            prop.put("charSet", "gb2312");     // 处理汉字问题
            String accessFilePath = "D:\\Documents\\JAVA\\student.mdb"; // 数据库文件路径
            Connection con = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=" + accessFilePath, prop);
            Statement  stmt = con.createStatement();

            // 对表student中所有学生进行查询,查询结果存放于ResultSet对象rs1中
            System.out.println("插入之前:");
            ResultSet rs1 = stmt.executeQuery("select * from student");
            while (rs1.next())
            {
                System.out.print("编号:" + rs1.getString("no") + "\t\t");   //使用列名称no获取列的数据
                System.out.print("姓名:" + new String(rs1.getBytes(2),"gbk") + "\t\t" ); //该列是汉字,不同于前列处理。获得第2列
                System.out.print("性别:" + new String(rs1.getBytes(3),"gbk") + "\t\t" ); //使用列的序号3,获得第3列性别
                System.out.println("成绩:" + rs1.getFloat("score") + "\t");         //使用score列对应的序号4获取该列的数据
            }

            //注意,执行insert语句时使用Statement的executeUpdate()方法,而不是executeQuery()方法
            //与executeQuery()方法不同,executeUpdate()方法不产生结果集ResultSet对象
            stmt.executeUpdate("INSERT INTO student VALUES('2005', '洛洛', '男', 97)");
            stmt.executeUpdate("INSERT INTO student VALUES( '2006', '小福贵', '男', 93)");
            stmt.executeUpdate("INSERT INTO student VALUES( '2007', '洛天依', '男', 80)");
            stmt.executeUpdate("INSERT INTO student VALUES( '2008', '江流儿', '男', 78)");
            stmt.executeUpdate("INSERT INTO student VALUES( '2009', '端木', '男', 86)");

            System.out.println("插入之后:");
            ResultSet rs2 = stmt.executeQuery("select * from student");
            while (rs2.next())
            {
                System.out.print("编号:" + rs2.getString("no") + "\t\t");   //使用列名称no获取列的数据
                System.out.print("姓名:" + new String(rs2.getBytes(2),"gbk") + "\t\t" ); //该列是汉字,不同于前列处理。获得第2列
                System.out.print("性别:" + new String(rs2.getBytes(3),"gbk") + "\t\t" ); //使用列的序号3,获得第3列性别
                System.out.println("成绩:" + rs2.getFloat("score") + "\t\t");         //使用score列对应的序号4获取该列的数据
            }

            rs1.close();
            rs2.close();
            stmt.close();   // 关闭连接和数据库
            con.close();
        }
        catch (Exception e)   // 捕捉JDBC在执行过程中出现的异常
        {
            System.out.println("SQLException:" + e.getMessage());
        }
    }
}
// 就不显示输出文字了。

  • 查询成绩超过80分的同学
import java.sql.*;
import java.util.*;

public class Main
{
    public static void main(String args[])
    {
        try
        {
            // 加载JDBC-ODBC桥接驱动程序
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        }
        catch (ClassNotFoundException ce)   //当无法载入JDBC驱动程序时捕捉异常
        {
            System.out.println("SQLException:" + ce.getMessage());
        }

        try
        {
            //连接数据源myDB,汉字编码采用GBK,否则显示汉字时可能会出现乱码
            Properties prop = new Properties();
            prop.put("charSet", "gb2312");     // 处理汉字问题
            String accessFilePath = "D:\\Documents\\JAVA\\student.mdb"; // 数据库文件路径
            Connection con = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=" + accessFilePath, prop);
            Statement  stmt = con.createStatement();

            // 查询成绩大于80分的学生
            ResultSet rs = stmt.executeQuery("select * from student where student.score > 80");
            while (rs.next())
            {
                System.out.print("编号:" + rs.getString("no") + "\t\t");   //使用列名称no获取列的数据
                System.out.print("姓名:" + new String(rs.getBytes(2),"gbk") + "\t\t" ); //该列是汉字,不同于前列处理。获得第2列
                System.out.print("性别:" + new String(rs.getBytes(3),"gbk") + "\t\t" ); //使用列的序号3,获得第3列性别
                System.out.println("成绩:" + rs.getFloat("score"));         //使用score列对应的序号4获取该列的数据
            }

            rs.close();
            stmt.close();   // 关闭连接和数据库
            con.close();
        }
        catch (Exception e)   // 捕捉JDBC在执行过程中出现的异常
        {
            System.out.println("SQLException:" + e.getMessage());
        }
    }
}

/*
编号:2001     姓名:貂蝉       性别:女        成绩:85.0
编号:2002     姓名:赵云       性别:男        成绩:95.0
编号:2004     姓名:周瑜       性别:男        成绩:98.0
编号:2005     姓名:洛洛       性别:男        成绩:97.0
编号:2006     姓名:小福贵      性别:男        成绩:93.0
编号:2009     姓名:端木       性别:男        成绩:86.0
*/

  • 按照成绩从大到小排序
import java.sql.*;
import java.util.*;

public class Main
{
    public static void main(String args[])
    {
        try
        {
            // 加载JDBC-ODBC桥接驱动程序
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        }
        catch (ClassNotFoundException ce)   //当无法载入JDBC驱动程序时捕捉异常
        {
            System.out.println("SQLException:" + ce.getMessage());
        }

        try
        {
            //连接数据源myDB,汉字编码采用GBK,否则显示汉字时可能会出现乱码
            Properties prop = new Properties();
            prop.put("charSet", "gb2312");     // 处理汉字问题
            String accessFilePath = "D:\\Documents\\JAVA\\student.mdb"; // 数据库文件路径
            Connection con = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=" + accessFilePath, prop);
            Statement  stmt = con.createStatement();

            // 成绩从大到小排序
            ResultSet rs = stmt.executeQuery("select * from student order by score desc");
            while (rs.next())
            {
                System.out.print("编号:" + rs.getString("no") + "\t\t");   //使用列名称no获取列的数据
                System.out.print("姓名:" + new String(rs.getBytes(2),"gbk") + "\t\t" ); //该列是汉字,不同于前列处理。获得第2列
                System.out.print("性别:" + new String(rs.getBytes(3),"gbk") + "\t\t" ); //使用列的序号3,获得第3列性别
                System.out.println("成绩:" + rs.getFloat("score"));         //使用score列对应的序号4获取该列的数据
            }

            rs.close();
            stmt.close();   // 关闭连接和数据库
            con.close();
        }
        catch (Exception e)   // 捕捉JDBC在执行过程中出现的异常
        {
            System.out.println("SQLException:" + e.getMessage());
        }
    }
}
/*
编号:2004     姓名:周瑜       性别:男        成绩:98.0
编号:2005     姓名:洛洛       性别:男        成绩:97.0
编号:2002     姓名:赵云       性别:男        成绩:95.0
编号:2006     姓名:小福贵      性别:男        成绩:93.0
编号:2009     姓名:端木       性别:男        成绩:86.0
编号:2001     姓名:貂蝉       性别:女        成绩:85.0
编号:2007     姓名:洛天依      性别:男        成绩:80.0
编号:2008     姓名:江流儿      性别:男        成绩:78.0
编号:2003     姓名:张飞       性别:男        成绩:75.0
*/


To be continued.
2018-04-22 星期日

转载原创文章请注明,转载自: 太傅 » JAVA上机实验笔记
  1. TaiFu_S

    保持“增量”更新 doge1

    1. TaiFu_S
      @TaiFu_S

      应该是最后一次作业了!miao3

  2. CongTsang

    啊,你怎么不等我!尴尬中刀

    1. TaiFu_S
      @CongTsang

      喷 你太慢了!

  3. Shawn

    越来越棒了|´・ω・)ノ

    1. TaiFu_S
      @Shawn

      嘿嘿,蟹蟹 太开心

      1. Shawn
        @TaiFu_S

        你关了pjax?

        1. TaiFu_S
          @Shawn

          对,因为那个表情的原因…没修bug

  4. Zombie.

    可以,很不错!

    1. TaiFu_S
      @Zombie.

      嘿嘿

  5. 曾

    不知道为什么,在我电脑上显示的这个Java实验笔记字体很小,看起来很吃力,

    1. TaiFu_S
      @曾

      或许换一个浏览器可以解决这个问题绿帽