第一章 常用类

第一章 常用类在这里插入图片描述

1.equals方法和=判断对象是否相等的区别

​ 1.== 既可以比较基本类型也可以比较引用类型。对于基本类型(byte,short,int,long,float,double,char,boolean)就是比较值,对于引用类型就是比较内存地址

​ 2.equals,如果该方法没有被重写过默认也是==;重写equals方法,会比较类中的相应属性是否都相等。(就是比较值)

2.equals方法和hashCode方法的关系

​ 1.在哈希表中,当插入或查找一个元素时,会先根据元素的hashCode值来确定该元素在哈希表中的位置,然后再使用equals方法进行比较,如果该位置上已经有元素,则需要比较该元素和要插入或查找的元素是否相等。

3.字符串操作类String、StringBuffer、StringBuilder的区别
  1. String是Java中最基本的字符串类,它是一个不可变的类,即一旦创建,它的值就不能被改变了。
  2. StringBuffer是一个可变的字符串类,它可以在原有字符串上进行添加、删除、替换等操作,
  3. StringBuffer是线程安全的,
  4. StringBuilder是自JDK5起引入的一个可变字符串类,它是线程不安全的,但具有和StringBuffer相同的操作性能。
4.String类的常用方法如
  1. length():获取字符串中字符的个数,即字符串的长度。
  2. isEmpty():判断字符串是否为空,即长度为0。
  3. startsWith(String prefix):判断该字符串是否以指定前缀字符串开头。
  4. trim():去掉字符串两端的空格,并返回一个新的字符串。
  5. subString(int beginIndex):获取从指定位置开始到字符串结尾的子字符串。
  6. subString(int beginIndex, int endIndex):获取从指定的开始位置到结束位置之间的子字符串,注意endIndex所在的字符不包含在结果中。
  7. replace(oldstr, newstr):将字符串中所有的旧字符串替换成新字符串,并返回一个新的字符串。
5.包装类的自动装箱和自动拆箱、包装类常用方法
 **装箱:把基本数据类型转为包装类对象**
 **拆箱:把包装类对象拆为基本数据类型**
Integer i = 4;//自动装箱。相当于Integer i = Integer.valueOf(4);
i = i + 5;//等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5;
//加法运算完成后,再次装箱,把基本数值转成对象。
**数据类型的最大最小值
	Integer.MAX_VALUE和Integer.MIN_VALUE
**字符转大小写
    Character.toUpperCase('x');
	Character.toLowerCase('X');
**整数转进制
    Integer.toBinaryString(int i) //二进制字符串
    
	Integer.toHexString(int i)//十六进制字符串
    
	Integer.toOctalString(int i)//八进制字符串
 ** 比较的方法
    Integer.compare(int x, int y) 
    
  ** Integer等包装类对象是“不可变”对象,即一旦修改,就是新对象,和实参就无关了
    b += 10;//等价于  b = new Integer(b+10);
6.SimpleDateFormat类对日期格式化和将字符串转换成Date对象的方法
//格式化日期为字符串	
 public String format(Date date)
//将字符串解析成Date对象
  public Date parse(String source) throws ParseException
     
     
//使用SimpleDateFormat类将Date对象格式化为字符串和将字符串解析成Date对象:
     
     
  	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		// 将Date对象格式化为字符串
	Date date = new Date();
	String strDate = dateFormat.format(date);
	System.out.println("格式化后的时间:" + strDate);

		// 将字符串解析成Date对象
	String str = "2023-06-09 10:07:47";
	Date parsedDate = dateFormat.parse(str);
	System.out.println("解析后的时间:" + parsedDate);

第二章 集合

1.Collection和Map的常用方法

Collection:

  • add(E e):向集合中添加一个元素。

  • remove(Object o):从集合中删除一个元素。

  • clear():删除集合中的所有元素。

  • size():返回集合中元素的个数。

  • isEmpty():判断集合是否为空。

  • contains(Object o):判断集合中是否包含指定元素。

  • iterator():返回一个用于遍历集合中元素的迭代器。

Map:

  • put(K key, V value):将一对键值对存入Map中。
  • get(Object key):根据键获取Map中对应的值。
  • remove(Object key):删除Map中指定键的键值对。
  • clear():删除Map中的所有键值对。
  • size():返回Map中键值对的个数。
  • isEmpty():判断Map是否为空。
  • containsKey(Object key):判断Map中是否包含指定键。
  • keySet():返回包含Map中所有键的Set集合。
2.List和Set的区别
  1. List是有序,可重复的,它可以保留元素的插入顺序;而Set是无序,不重复的,它不会保留元素的插入顺序。
  2. List可以根据下标访问元素;而Set不能通过下标访问元素,只能通过迭代器访问元素。
3.Collection和Map的区别
  1. Collection接口是一组对象的集合,可以用来保存一组对象;而Map接口是一组键-值对(key-value)的映射集合,每个键对应一个值
  2. ​ Collection接口中可以保存重复的元素,但是Map接口中的键是唯一的,不允许重复。
  3. Collection接口中的元素是通过迭代器进行访问的,而Map接口中的元素可以通过键来进行访问。
4.ArrayList和LinkedList的区别
  1. ArrayList内部用数组实现的,而LinkedList内部是用双向链表实现的。

  2. ArrayList底层采用数组实现,支持快速随机访问,例如get和set操作是常数时间的(O(1)),但它的插入和删除操作是线性时间的(O(n))。

  3. LinkedList底层采用双向链表实现,因此它的插入和删除操作是常数时间的(O(1)),但它的随机访问性能相对较差,例如get和set操作需要遍历链表(O(n))。

5.Iterator遍历集合
@Test
    public void test02(){
        Collection coll = new ArrayList();
        coll.add("小李广");
        coll.add("扫地僧");
        coll.add("石破天");

        Iterator iterator = coll.iterator();//获取迭代器对象
        while(iterator.hasNext()) {//判断是否还有元素可迭代
            System.out.println(iterator.next());//取出下一个元素
        }
    }
6.HashMap的遍历
for (Object obj : hashMap.keySet()) {
			System.out.println(obj + "=" + hashMap.get(obj));
			}
7.TreeSet实现自然排序和定制排序
 //自然排序,针对string的
 @Test
    public void test1(){
        TreeSet set = new TreeSet();

        set.add("MM");
        set.add("CC");
        set.add("AA");
        set.add("DD");
        set.add("ZZ");
        
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }


/**定制排序
 * */
@Test
public void test3(){
    //按照User的姓名的从小到大的顺序排列
    Comparator comparator = new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
            if(o1 instanceof User && o2 instanceof User){
                User u1 = (User)o1;
                User u2 = (User)o2;

                return u1.name.compareTo(u2.name);
            }
            throw new RuntimeException("输入的类型不匹配");
        }
    };
    TreeSet set = new TreeSet(comparator);

    set.add(new User("Tom",12));
    set.add(new User("Rose",23));
    set.add(new User("Jerry",2));
    set.add(new User("Eric",18));
    set.add(new User("Tommy",44));
    set.add(new User("Jim",23));
    set.add(new User("Maria",18));
    //set.add(new User("Maria",28));

    Iterator iterator = set.iterator();
    while(iterator.hasNext()){
        System.out.println(iterator.next());
    }
}

/*
    举例:按照age从小到大的顺序排列,如果age相同,则按照name从大到小的顺序排列
    * */
    public int compareTo(Object o) {
        if(this == o){
            return 0;
        }

        if(o instanceof User){
            User user = (User)o;
            int value = this.age - user.age;
            if(value != 0){
                return value;
            }
            return -this.name.compareTo(user.name);
        }
        throw new RuntimeException("输入的类型不匹配");
    }
}
8.Collections和Arrays工具类的常用方法

​ .Collections

  • sort(List list):对列表进行排序。
  • reverse(List list):将列表中的元素翻转。
  • binarySearch(List<?> list, T key):使用二分搜索算法查找指定元素在列表中的索引。
  • fill(List<? super T> list, T obj):使用指定的对象填充列表中的所有元素。
  • max(Collection<? extends T> coll):返回指定集合中的最大元素。
  • min(Collection<? extends T> coll):返回指定集合中的最小元素。
  • frequency(Collection<?> c, Object o):返回指定集合中指定元素出现的次数。
  • shuffle(List<?> list):随机打乱列表中的元素顺序。
  • disjoint(Collection<?> c1, Collection<?> c2):判断两个集合是否有交集。

​ Arrays

  • sort(T[] a):对数组进行排序。
  • binarySearch(T[] a, T key):使用二分搜索算法查找指定元素在数组中的索引。
  • equals(T[] a, T[] a2):判断两个数组是否相等。
  • fill(T[] a, T val):使用指定的值填充数组中的所有元素。
  • copyOf(T[] original, int newLength):将一个数组复制到一个新数组,新数组长度为newLength,超出部分会被填充默认值。
  • toString(T[] a):返回一个包含数组中所有元素的字符串表示形式。
9.泛型类、泛型接口、泛型方法的语法,使用方法
//泛型类
public class MyClass<T> {
    private T value;

    public MyClass(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }
}

MyClass<String> myClass1 = new MyClass<>("Hello");
MyClass<Integer> myClass2 = new MyClass<>(123);
String str = myClass1.getValue();
int num = myClass2.getValue();


//泛型接口
public interface MyInterface<T> {
    T getValue();
}

public class MyClass implements MyInterface<String> {
    @Override
    public String getValue() {
        return "Hello";
    }
}


//泛型方法
public class MyUtils {
    public static <T> void print(T[] arr) {
        for (T item : arr) {
            System.out.println(item);
        }
    }
}

String[] arr1 = {"Hello", "World"};
Integer[] arr2 = {1, 2, 3};
MyUtils.print(arr1);  // 自动推断为 T 为 String 类型
MyUtils.print(arr2);  // 自动推断为 T 为 Integer 类型
10.使用泛形的好处
  1. ​ 类型安全:Java泛型可以让编译器在编译时检查类型,从而避免了类型转换错误和类型不匹配的运行时异常
  2. ​ 代码重用:使用泛型可以创建可重用的代码,可以在不同类型上运行。
  3. 性能优化:使用泛型可以避免对基本类型进行装箱和拆箱操作,从而提高程序的执行效率

第三章 多线程

1.线程的三种创建方式及其区别

​ 方式一:继承Thread类

​ 方式二:实现Runnable接口

​ 方式三:实现Callable接口

区别:

  • 继承Thread:线程代码存放Thread子类run方法中。

  • 实现Runnable:线程代码存在接口的子类的run方法。

  • 实现Callable接口:线程需要执行的操作声明在call()中

2.线程的状态及状态转换

NEW(新建):线程刚被创建,但是并未启动。还没调用start方法。

RUNNABLE(可运行):这里没有区分就绪和运行状态。

Teminated(被终止):表明此线程已经结束生命周期,终止运行。

TIMED_WAITING(计时等待)

WAITING(无限等待)

image-20230612094136703
3.线程调度之线程优先级、线程休眠、线程让步、线程插队等
Thread类的三个优先级常量:
  • MAX_PRIORITY(10):最高优先级
  • MIN _PRIORITY (1):最低优先级
  • NORM_PRIORITY (5):普通优先级,默认情况下main线程具有普通优先级。
  • public final int getPriority() :返回线程优先级

  • public final void setPriority(int newPriority) :改变线程的优先级,范围在[1,10]之间。

    线程休眠

    sleep():使当前线程休眠指定的毫秒数

    线程让步

    yield():让当前线程释放CPU资源,以便让其他线程使用

    线程插队

    join():方法会阻塞当前线程,直到被等待的线程执行完毕。

4.线程同步之synchronized和ReentrantLock实现线程同步
synchronized

​ 同步代码块

synchronized(同步锁){
     需要同步操作的代码
}

​ 同步方法

public synchronized void method(){
    可能会产生线程安全问题的代码
}
ReentrantLock
class A{
    //1. 创建Lock的实例,必须确保多个线程共享同一个Lock实例
	private final ReentrantLock lock = new ReenTrantLock();
	public void m(){
        //2. 调动lock(),实现需共享的代码的锁定
		lock.lock();
		try{
			//保证线程安全的代码;
		}
		finally{
            //3. 调用unlock(),释放共享代码的锁定
			lock.unlock();  
		}
	}
}
5.线程死锁的解决方式及其实现
  1. 采用统一的获取资源的顺序
  2. 检测和恢复死锁:
  3. 使用超时等待机制

第四章 IO流

1.File类的常用方法
  1. exists()方法:判断文件或目录是否存在,返回布尔类型的值true或false。

  2. isFile()方法:判断是否是一个文件,如果是返回true,否则返回false。

  3. isDirectory()方法:判断是否是一个目录,如果是返回true,否则返回false。

  4. length()方法:获取文件的大小,返回一个long类型的值表示文件的字节数。

  5. listFiles()方法:获取目录下的所有文件和子目录,返回一个File数组,数组中的每个元素是目录下的一个文件或目录。如果该File对象不是一个目录,则返回null。

2.递归删除目录文件
public static void deleteDir(File dir) {
        if (dir.isDirectory()) {
            File[] children = dir.listFiles();
            for (File child : children) {
                deleteDir(child);
            }
        }
        boolean success = dir.delete();
        if (success) {
            System.out.println("已经成功删除:" + dir.getAbsolutePath());
        } else {
            System.out.println("删除失败:" + dir.getAbsolutePath());
        }
    }

    public static void main(String[] args) {
        File directory = new File("C:/temp");
        deleteDir(directory);
    }
3.流的分类
  • 按数据的流向不同分为:输入流输出流

    • 输入流 :把数据从其他设备上读取到内存中的流。
      • 以InputStream、Reader结尾
    • 输出流 :把数据从内存 中写出到其他设备上的流。
      • 以OutputStream、Writer结尾
  • 按操作数据单位的不同分为:字节流(8bit)字符流(16bit)

    • 字节流 :以字节为单位,读写数据的流。
      • 以InputStream、OutputStream结尾
    • 字符流 :以字符为单位,读写数据的流。
      • 以Reader、Writer结尾
  • 根据IO流的角色不同分为:节点流处理流

    节点流:直接从数据源或目的地读写数据

    处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。

4.字符流和字节流的区别
  1. 字节流按字节读取和写入数据。它们可以用于读取和写入任何类型的数据,包括二进制数据和文本数据。
  2. 字符流按字符或字符串读取和写入数据。它们只能用于读取和写入文本数据
  3. 字符流内部使用了缓冲区,因此在输入和输出时效率较高
  4. 字符流能够自动处理 Unicode 编码的字符。字节流只能处理 ASCII 编码的字符。
5.常用字符流和常用字节流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GM1RGEyU-1686746832995)(C:\Users\李\AppData\Roaming\Typora\typora-user-images\image-20230612143624328.png)]

6.利用字符流或字节流复制文件夹级文件

看实验

7.字节缓冲流的创建及用法
  1. 创建字节缓冲输入流(输出同理)
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file.txt"));

2.读取数据

byte[] buffer = new byte[1024];
int bytesRead = bis.read(buffer);

3.写入数据

byte[] buffer = "Hello World!".getBytes();
bos.write(buffer);

4.关闭

 bis.close();
 bos.close();
8.转换流的创建及用法
public class ConvertStreamDemo {
    public static void main(String[] args) throws IOException {
        // 创建 InputStreamReader 对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream("input.txt"), "UTF-8");

        // 创建 OutputStreamWriter 对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8");

        // 读取数据并写入到输出流中
        int c = isr.read();
        while (c != -1) {
            osw.write(c);
            c = isr.read();
        }

        // 关闭流
        isr.close();
        osw.close();
    }
9.对象序列化

第五章 注解

1.Java常用注解
  1. @Override:标记方法重写父类的方法
  2. @Deprecated:标记该方法已经过时,不推荐使用。
2.元注解有哪些,各自的作用
  1. @Target:用于指定注解的应用范围,可以用于类、方法、参数等
  2. @Retention:用于指定注解的生命周期,可以在编译期、运行期或者是类加载期存在。
  3. @Documented:用于指定被注解的类、方法、字段等是否包含在文档中。
  4. @Inherited:用于指定被注解的类是否可以被继承,如果一个类使用了被@Inherited注解的注解,则其子类也会自动继承该注解。
  5. @Repeatable:用于指定注解是否可以重复。

第六章 网络编程

1.TCP/IP网络协议模型
  1. 数据链路层
  2. 网络层
  3. 传输层
  4. 应用层
2.URL编程

URL的基本结构由5部分组成:

​ <传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表

URL url = new URL("http://localhost:8080/examples/myTest.txt");
System.out.println("getProtocol() :"+url.getProtocol());//获取该URL的协议名
System.out.println("getHost() :"+url.getHost());//获取该URL的主机名
System.out.println("getPort() :"+url.getPort());//获取该URL的端口号
System.out.println("getPath() :"+url.getPath());//获取该URL的文件路径
System.out.println("getFile() :"+url.getFile());//获取该URL的文件路径
System.out.println("getQuery() :"+url.getQuery());//获取该URL的查询名
3.TCP和UDP协议的区别及各自的适用场景

区别:

  • 1.TCP是面向连接的,UDP是面向无连接
    无连接:发送数据之前不需要建立连接
  • 2.TCP是可靠传输,UDP是不可靠
    不可靠:收到报文后不需要给出任何确认
  • 3.TCP只支持点对点通信,UDP支持一对一,一对多,多对一,多对多。
  • 4.TCP是面向字节流的,UDP是面向报文的
    字节流:以字节为单位,可以分成若干组发送,报文:只能一次发完。
  • 5.TCP有拥塞控制机制,UDP没有
  • 6.TCP首部开销(20字节)比UDP首部开销(8字节)大
  • 7.UDP的主机不需要维持复杂的连接状态表

TCP适应场景:文件传输、网页浏览、邮件发送

UDP适应场景:音频、视频和普通数据的传输。例如视频会议

4.TCP通信和UDP通信编程
TCP
//服务器

package com.atguigu.tcp.one;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args)throws Exception {
        //1、准备一个ServerSocket对象,并绑定8888端口
        ServerSocket server =  new ServerSocket(8888);
        System.out.println("等待连接....");

        //2、在8888端口监听客户端的连接,该方法是个阻塞的方法,如果没有客户端连接,将一直等待
        Socket socket = server.accept();
        InetAddress inetAddress = socket.getInetAddress();
        System.out.println(inetAddress.getHostAddress() + "客户端连接成功!!");

        //3、获取输入流,用来接收该客户端发送给服务器的数据
        InputStream input = socket.getInputStream();
        //接收数据
        byte[] data = new byte[1024];
        StringBuilder s = new StringBuilder();
        int len;
        while ((len = input.read(data)) != -1) {
            s.append(new String(data, 0, len));
        }
        System.out.println(inetAddress.getHostAddress() + "客户端发送的消息是:" + s);

        //4、获取输出流,用来发送数据给该客户端
        OutputStream out = socket.getOutputStream();
        //发送数据
        out.write("欢迎登录".getBytes());
        out.flush();

        //5、关闭socket,不再与该客户端通信
        //socket关闭,意味着InputStream和OutputStream也关闭了
        socket.close();

        //6、如果不再接收任何客户端通信,可以关闭ServerSocket
        server.close();
    }
}

//客户端

package com.atguigu.tcp.one;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {

    public static void main(String[] args) throws Exception {
        // 1、准备Socket,连接服务器,需要指定服务器的IP地址和端口号
        Socket socket = new Socket("127.0.0.1", 8888);

        // 2、获取输出流,用来发送数据给服务器
        OutputStream out = socket.getOutputStream();
        // 发送数据
        out.write("lalala".getBytes());
        //会在流末尾写入一个“流的末尾”标记,对方才能读到-1,否则对方的读取方法会一致阻塞
        socket.shutdownOutput();

        //3、获取输入流,用来接收服务器发送给该客户端的数据
        InputStream input = socket.getInputStream();
        // 接收数据
        byte[] data = new byte[1024];
        StringBuilder s = new StringBuilder();
        int len;
        while ((len = input.read(data)) != -1) {
            s.append(new String(data, 0, len));
        }
        System.out.println("服务器返回的消息是:" + s);

        //4、关闭socket,不再与服务器通信,即断开与服务器的连接
        //socket关闭,意味着InputStream和OutputStream也关闭了
        socket.close();
    }
}

UDP
//发送端

package com.atguigu.udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;

public class Send {

    public static void main(String[] args)throws Exception {
//		1、建立发送端的DatagramSocket
        DatagramSocket ds = new DatagramSocket();

        //要发送的数据
        ArrayList<String> all = new ArrayList<String>();
        all.add("尚硅谷让天下没有难学的技术!");
        all.add("学高端前沿的IT技术来尚硅谷!");
        all.add("尚硅谷让你的梦想变得更具体!");
        all.add("尚硅谷让你的努力更有价值!");

        //接收方的IP地址
        InetAddress ip = InetAddress.getByName("127.0.0.1");
        //接收方的监听端口号
        int port = 9999;
        //发送多个数据报
        for (int i = 0; i < all.size(); i++) {
//			2、建立数据包DatagramPacket
            byte[] data = all.get(i).getBytes();
            DatagramPacket dp = new DatagramPacket(data, 0, data.length, ip, port);
//			3、调用Socket的发送方法
            ds.send(dp);
        }

//		4、关闭Socket
        ds.close();
    }
}
//接收端

package com.atguigu.udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Receive {

    public static void main(String[] args) throws Exception {
//		1、建立接收端的DatagramSocket,需要指定本端的监听端口号
        DatagramSocket ds = new DatagramSocket(9999);

        //一直监听数据
        while(true){
            //2、建立数据包DatagramPacket
            byte[] buffer = new byte[1024*64];
            DatagramPacket dp = new DatagramPacket(buffer,buffer.length);

            //3、调用Socket的接收方法
            ds.receive(dp);

            //4、拆封数据
            String str = new String(dp.getData(),0,dp.getLength());
            System.out.println(str);
        }

//        ds.close();
    }
}

第七章 JDBC

1.数据库驱动注册
Class.forName("com.mysql.cj.jdbc.Driver" );
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mydatabase", "username", "password");
2.DriverManager类主要方法
  1. registerDriver(Driver driver): 注册一个数据库驱动程序。
  2. getDriver(String url): 通过指定JDBC URL获取对应的数据库驱动程序。
  3. getConnection(String url, String user, String password): 建立一个数据库连接。
  4. setLoginTimeout(int seconds): 设置JDBC驱动程序的登录超时时间(以秒为单位)。
  5. setLogWriter(PrintWriter out): 设置JDBC驱动程序的日志输出流。
3.Connection类常用方法
  1. createStatement():创建一个Statement对象以便执行SQL语句。
  2. prepareStatement(String sql):创建一个预编译的PreparedStatement对象以便执行SQL语句。
  3. setAutoCommit(boolean autoCommit):设置是否自动提交事务。
  4. commit():提交当前处于事务状态的操作。
  5. rollback():回滚当前处于事务状态的操作。
  6. close():关闭Connection对象。
4.Statement和PreparedStatement的区别

​ 1.PreparedStatement在使用时只需要编译一次,就可以运行多次,Statement每运行一次就编译一次,所以PreparedStatement的效率更高
​ 2.PreparedStatement需要的sql语句为用?(占位符)来替换值,Statement所需要的sql语句为字符串拼接
​ 3.PreparedStatement解决了sql注入的问题,Statement没有解决,

5.使用PreparedStatement执行增删改查操作
	//通用的增、删、改操作(体现一:增、删、改 ; 体现二:针对于不同的表)
	public void update(String sql,Object ... args){
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			//1.获取数据库的连接
			conn = JDBCUtils.getConnection();//JDBCUtils是自己写的
			
			//2.获取PreparedStatement的实例 (或:预编译sql语句)
			ps = conn.prepareStatement(sql);
			//3.填充占位符
			for(int i = 0;i < args.length;i++){
				ps.setObject(i + 1, args[i]);
			}
			
			//4.执行sql语句
			ps.execute();
		} catch (Exception e) {
			
			e.printStackTrace();
		}finally{
			//5.关闭资源
			JDBCUtils.closeResource(conn, ps);
			
		}
	}

6.ResultSet操作查询结果集
// 通用的针对于不同表的查询:返回一个对象 (version 1.0)
public <T> T getInstance(Class<T> clazz, String sql, Object... args) {

	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		// 1.获取数据库连接
		conn = JDBCUtils.getConnection();

		// 2.预编译sql语句,得到PreparedStatement对象
		ps = conn.prepareStatement(sql);

		// 3.填充占位符
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}

		// 4.执行executeQuery(),得到结果集:ResultSet
		rs = ps.executeQuery();

		// 5.得到结果集的元数据:ResultSetMetaData
		ResultSetMetaData rsmd = rs.getMetaData();

		// 6.1通过ResultSetMetaData得到columnCount,columnLabel;通过ResultSet得到列值
		int columnCount = rsmd.getColumnCount();
		if (rs.next()) {
			T t = clazz.newInstance();
			for (int i = 0; i < columnCount; i++) {// 遍历每一个列

				// 获取列值
				Object columnVal = rs.getObject(i + 1);
				// 获取列的别名:列的别名,使用类的属性名充当
				String columnLabel = rsmd.getColumnLabel(i + 1);
				// 6.2使用反射,给对象的相应属性赋值
				Field field = clazz.getDeclaredField(columnLabel);
				field.setAccessible(true);
				field.set(t, columnVal);

			}

			return t;

		}
	} catch (Exception e) {

		e.printStackTrace();
	} finally {
		// 7.关闭资源
		JDBCUtils.closeResource(conn, ps, rs);
	}

	return null;

}
7.JDBC编程步骤
  1. 加载数据库驱动
  2. 建立数据库连接
  3. 执行SQL语句
  4. 处理查询结果集
  5. 提交事务或回滚事务
  6. 释放资源

第八章 反射

1.反射的作用

1.动态加载类

public class ReflectionTest {
    //体会反射的动态性:动态的创建指定字符串对应类的对象,并调用指定的方法
    public Object  invoke(String className,String methodName) throws Exception {
        Class clazz = Class.forName(className);
        Constructor constructor = clazz.getDeclaredConstructor();
        constructor.setAccessible(true);
        //动态的创建指定字符串对应类的对象
        Object obj = constructor.newInstance();

        Method method = clazz.getDeclaredMethod(methodName);
        method.setAccessible(true);
        return method.invoke(obj);
    }

    @Test
    public void test2() throws Exception {
        String info = (String) invoke("com.atguigu.java1.Person", "show");

        System.out.println("返回值为:" + info);

    }
}

2.获取类的构造函数

3.动态创建对象

4.调用私有方法

5.广泛应用于框架

2.获取Class类对象的三种方式

通过类的class属性获取

Class clazz = String.class;

调用该实例的getClass()方法获取Class对象

Class clazz = "www.atguigu.com".getClass();

通过Class类的静态方法forName()获取

Class clazz = Class.forName("java.lang.String");
3.Class类的常用方法

获取类的构造方法列表

Constructor<?>[] constructors = clazz.getConstructors(); // 获取所有公共构造方法列表
Constructor<?>[] constructors = clazz.getDeclaredConstructors(); // 获取所有构造方法列表(包括私有构造方法)
Constructor<?> constructor = clazz.getConstructor(Class<?>... parameterTypes); // 获取指定参数列表的公共构造方法
Constructor<?> constructor = clazz.getDeclaredConstructor(Class<?>... parameterTypes); // 获取指定参数列表的构造方法(包括私有构造方法)

获取类的接口列表

Class<?>[] interfaces = clazz.getInterfaces(); // 获取当前类的接口列表
Class<?> superclass = clazz.getSuperclass(); 获取当前类的父类

获取类的属性列表:

Field[] fields = clazz.getFields(); // 获取所有公共属性列表(包括父类的公共属性)
Field[] fields = clazz.getDeclaredFields(); // 获取所有属性列表(包括私有属性)
Field field = clazz.getField(String name); // 获取指定名称的公共属性
Field field = clazz.getDeclaredField(String name); // 获取指定名称的属性(包括私有属性)

获取类的方法列表:

Method[] methods = clazz.getMethods(); // 获取所有公共方法列表(包括父类的公共方法)
Method[] methods = clazz.getDeclaredMethods(); // 获取所有方法列表(包括私有方法)
Method method = clazz.getMethod(String name, Class<?>... parameterTypes); // 获取指定名称和参数列表的公共方法
Method method = clazz.getDeclaredMethod(String name, Class<?>... parameterTypes); // 获取指定名称和参数列表的方法(包括私有方法)
4.反射机制操作获取和设置属性值
public class Main {
    public static void main(String[] args) throws Exception {
        Person person = new Person("Tom", 18);

        // 获取属性名称、类型和修饰符等信息
        Field nameField = person.getClass().getDeclaredField("name");
        String name = nameField.getName();
        Class<?> type = nameField.getType();
        int modifiers = nameField.getModifiers();

        // 获取属性值
        Object value = nameField.get(person);
        System.out.println(name + " = " + value);

        // 设置属性值
        nameField.set(person, "Jerry");
        value = nameField.get(person);
        System.out.println(name + " = " + value);
    }
5.通过反射机制获取属性的getter/setter方法操作属性
public class Main {
    public static void main(String[] args) throws Exception {
        Person person = new Person("Tom", 18);

        // 获取setter方法
        Method setNameMethod = person.getClass().getMethod("setName", String.class);
        // 设置属性值
        setNameMethod.invoke(person, "Jerry");

        // 获取getter方法
        Method getNameMethod = person.getClass().getMethod("getName");
        // 获取属性值
        Object name = getNameMethod.invoke(person);
        System.out.println(name);
    }

第九章 Swing

1.JFrame类

​ 顶级容器类之一,它提供了一个框架来在屏幕上创建、调整和显示GUI应用程序窗口。

  • setTitle():设置窗口的标题。
  • setSize():设置窗口的大小。
  • setLayout():设置容器的布局管理器。
  • setDefaultCloseOperation():设置窗口关闭时的操作。
  • setVisible():显示或隐藏窗口。
2.常用布局管理器及其布局方式
  1. BorderLayout:将容器划分为五个区域:北、南、东、西和中心,每个区域放置一个组件。
  2. FlowLayout:按照添加的组件顺序依次摆放,如果超出容器范围则自动换行,类似于文字排版。
  3. GridLayout:将容器划分为若干行、若干列的网格,并按照顺序依次向网格中添加组件。
  4. CardLayout:将容器中的每个组件视为一张卡片,只显示当前卡片,可以通过切换卡片来显示不同的组件内容。
  5. BoxLayout:按照水平或垂直方向将组件依次排列。
3.Swing事件处理流程

事件源注册监听器

监听器实现:

事件分派

事件处理

事件反馈

4.Swing常用事件处理
  1. ActionEvent:当组件(例如按钮或菜单项)被用户点击时触发。
  2. MouseEvent:当鼠标与组件交互时触发事件。
  3. FocusEvent:当组件获得或失去焦点时触发事件。
  4. WindowEvent:当窗口(例如JFrame或JDialog)的状态发生变化时(例如打开或关闭)触发事件。
  5. KeyEvent:该事件与键盘交互有关,例如键盘按下、松开或敲击等。
  6. MouseWheelEvent:该事件与鼠标滚轮有关。
  7. ListSelectionEvent:该事件在用户选择决定性更改时触发,要么将某项选中,要么取消某项选中。
5.中间容器组件JScrollPane、JPanel的用法
  1. JScrollPane组件一般用于容纳视图或容器,并提供一个可滚动的视窗。
  2. JPanel是一个空白容器,可以用来组织其他组件,它常作为其他布局管理器的容器。
6.Swing常用组件用法

JLabel是一个用于显示文本或图像的组件。

JTextField是一个文本输入框组件,用户可以在其中输入文本。

JButton是一个按钮组件,用户可以单击它执行某些操作。

JCheckBox是一个复选框组件,用户可以选中或取消选中它,常用于表示二进制选项。

ame类

​ 顶级容器类之一,它提供了一个框架来在屏幕上创建、调整和显示GUI应用程序窗口。

  • setTitle():设置窗口的标题。
  • setSize():设置窗口的大小。
  • setLayout():设置容器的布局管理器。
  • setDefaultCloseOperation():设置窗口关闭时的操作。
  • setVisible():显示或隐藏窗口。
2.常用布局管理器及其布局方式
  1. BorderLayout:将容器划分为五个区域:北、南、东、西和中心,每个区域放置一个组件。
  2. FlowLayout:按照添加的组件顺序依次摆放,如果超出容器范围则自动换行,类似于文字排版。
  3. GridLayout:将容器划分为若干行、若干列的网格,并按照顺序依次向网格中添加组件。
  4. CardLayout:将容器中的每个组件视为一张卡片,只显示当前卡片,可以通过切换卡片来显示不同的组件内容。
  5. BoxLayout:按照水平或垂直方向将组件依次排列。
3.Swing事件处理流程

事件源注册监听器

监听器实现:

事件分派

事件处理

事件反馈

4.Swing常用事件处理
  1. ActionEvent:当组件(例如按钮或菜单项)被用户点击时触发。
  2. MouseEvent:当鼠标与组件交互时触发事件。
  3. FocusEvent:当组件获得或失去焦点时触发事件。
  4. WindowEvent:当窗口(例如JFrame或JDialog)的状态发生变化时(例如打开或关闭)触发事件。
  5. KeyEvent:该事件与键盘交互有关,例如键盘按下、松开或敲击等。
  6. MouseWheelEvent:该事件与鼠标滚轮有关。
  7. ListSelectionEvent:该事件在用户选择决定性更改时触发,要么将某项选中,要么取消某项选中。
5.中间容器组件JScrollPane、JPanel的用法
  1. JScrollPane组件一般用于容纳视图或容器,并提供一个可滚动的视窗。
  2. JPanel是一个空白容器,可以用来组织其他组件,它常作为其他布局管理器的容器。
6.Swing常用组件用法

JLabel是一个用于显示文本或图像的组件。

JTextField是一个文本输入框组件,用户可以在其中输入文本。

JButton是一个按钮组件,用户可以单击它执行某些操作。

JCheckBox是一个复选框组件,用户可以选中或取消选中它,常用于表示二进制选项。

JRadioButton是一个单选按钮组件,用户可以从一组选择项中选中一个,常用于组织选项。

在这里插入图片描述
LXY

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值