文章目录
- day04_Java高级
- 一、今日课程内容
- 二、可变参数
- 三、Java的集合
- 1、单列集合
- 1.1 List集合
- 1.2 常见的数据结构(了解)
- 1.3 Set集合
- 1.4 哈希表
- 2、双列集合
- 3、Collections集合工具类
- 四、(掌握)Lambda表达式
- 1、体验Lambda表达式
- 2、Lambda表达式的标准格式
- 3、Lambda省略模式
- 4、Lambda表达式和匿名内部类的区别
- 五、JDBC协议
- 1、JDBC原理
- 2、JDBC入门案例
- 2.1 查询表中数据
- 2.2 如何添加数据
- 2.3 如何修改数据
- 2.4 如何删除数据
day04_Java高级
一、今日课程内容
- 可变参数(熟悉)
- Java的集合(掌握)
- lambda表达式(掌握)
- JDBC的协议(熟悉,JavaEE的框架)
二、可变参数
如果遇到让我们定义一些方法, 分别获取2个整数, 3个整数, 4个整数的和, 此时我们只能通过方法重载的形式来实现, 但是这样做比较繁琐, 我们发现上述的这些方法, 只有参数列表是变化的, 那能不能优化这个问题呢?
肯定是可以的, 我们可以通过可变参数来优化这个问题.
可变参数又称参数个数可变,它用作方法的形参出现,那么方法参数个数就是可变的了
格式:
修饰符 返回值类型 方法名(形参1,形参2,数据类型… 变量名) { }说明:可变参数的底层就是一个数组. 方法的形参列表有且只能有一个可变参数, 并且可变参数要放到形参列表的最后.
需求:
- 1- 定义getSum()方法, 用来获取n个整数的和(n可能是任意的一个数字).
- 2- 在main方法中, 调用getSum()方法.
java">package com.itheima.day04;public class 可变参数 {public static void main(String[] args) {System.out.println(getSum("a",1, 2));System.out.println(getSum("a",1, 2, 3));System.out.println(getSum("a",1, 2, 3, 4, 5, 6, 7));}/*可变参数有两个注意事项:1- 可变参数只允许放在参数列表的最末尾2- 一个方法的形参中,只允许最多有一个可变参数*/public static int getSum(String name,int... nums){System.out.println(nums.length);int result = 0;for (int num : nums) {result += num;}return result;}// public static int getSum(int num1,int num2){
// int result = num1 + num2;
// return result;
// }
//
// public static int getSum(int num1,int num2,int num3){
// int result = num1 + num2 + num3;
// return result;
// }
}
三、Java的集合
Python中List、Set、Dict
集合体系图:
记忆
集合的顶层都是接口, 其中Collection接口是单列集合的顶层接口, Map接口是双列集合的顶层接口Collection接口(单列集合)有两大子体系:1.List体系的特点是: 有序, 可重复2.Set体系的特点是: 无序, 唯一一个小技巧: 以后但凡我们学习一个新的体系时, 都建议采用学顶层, 用底层的方式来学习.解释: 因为顶层封装的是整个继承体系的共性内容, 而底层才是具体的实现, 体现.
1、单列集合
集合是用来存储多个同类型数据的容器, 它的长度是可以变化的.
collection常用方法如下:
1.public boolean add(E e) 添加元素.
2.public boolean remove(Object obj) 从集合中移除指定的元素.
3.public void clear() 清空集合对象
4.public boolean contains(Object obj) 判断集合中是否包含指定的元素
5.public boolean isEmpty() 判断集合是否为空
6.public int size() 获取集合的长度, 即集合中元素的个数
7.public Iterator<E> iterator() //根据集合对象, 获取其对应的迭代器对象.Iterator迭代器中的方法: public boolean hasNext() //判断迭代器中是否还有下一个元素.public E next() //获取迭代器中的下一个元素.
1.1 List集合
List集合的元素特点是: 有序, 可重复, 元素有索引.
- 有序: 指的是元素的存储顺序和取出顺序是一致的.
- 可重复: 指的是List集合可以存储重复的元素.
- 元素有索引: 指的是List集合中每个元素都是由索引的, 且索引是从0开始的.
- 集合中只能存储相同类型的元素;只有正向索引,没有负向索引。
相关的方法:
public void add(int index, E element)
解释: 在集合的指定位置(索引), 插入指定的元素, 索引越界会报IndexOutOfBoundsException异常.
public E remove(int index)
解释: 删除指定索引处的元素, 并返回被删除的元素, 索引越界会报IndexOutOfBoundsException异常.
public E set(int index, E element)
解释: 修改指定索引处的元素为指定的值, 并返回修改前的元素, 索引越界会报IndexOutOfBoundsException异常.
public E get(int index)
解释: 根据索引, 获取其对应的元素, 索引越界会报IndexOutOfBoundsException异常.
List集合是一个接口, 其常用子类主要有两个, 分别为ArrayList, LinkedList
1.ArrayList集合的特点: 底层数据结构是数组, 查询和修改快, 增删慢.
2.LinkedList集合的特点: 底层数据结构是链表, 查询和修改慢, 增删快. 注意: 它们的相同点是, 都是有序的, 而且可以存储重复元素.
基础的collection相关API使用
java">package com.itheima.list单列集合;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class Test01_ArrayList集合 {public static void main(String[] args) {// 1. 创建ArrayList集合对象// list: 有序的(添加顺序和存储顺序存在关系) 可重复List<Integer> list = new ArrayList<>();//2. 执行相关的操作:// 2.1 添加数据list.add(10);list.add(20);list.add(25);list.add(30);list.add(20);// 2.2 在指定位置添加数据list.add(2,100);// 2.3 将指定的位置的元素进行修改list.set(2,150);System.out.println(list);// 2.4 如何获取元素Integer e1 = list.get(0);System.out.println(e1);Integer e2 = list.get(3);System.out.println(e2);// 2.5 获取集合的长度int size = list.size();System.out.println(size);// 2.6 遍历元素System.out.println("--------------");// 普通for循环for(int i = 0 ; i< list.size(); i++){System.out.println(list.get(i));}System.out.println("--------------");// 普通while循环int i = 0 ;while(i< list.size()){System.out.println(list.get(i));i++;}System.out.println("--------------");// 增强for循环for (Integer e : list) {System.out.println(e);}System.out.println("--------------");// 基于迭代器进行Iterator<Integer> iterator = list.iterator();/*Boolean hasNext() : 判断是否还有下一个元素, 如果有 返回True 如果没有返回FalseT next(); 获取下一个元素, 返回的就是下一个元素的值*/while (iterator.hasNext()){Integer e = iterator.next();System.out.println(e);}// 2.7 判断某个元素是否存在boolean flag = list.contains(1500);System.out.println(flag);// 2.8 删除元素flag = list.remove((Object)150);System.out.println(flag);Integer e = list.remove(2);System.out.println("删除的元素为:"+ e);// 2.9 清空集合// 2.9.1 判断 集合是否为空System.out.println(list.isEmpty());// 2.9.2 执行清空list.clear();// 2.9.3 再次判断集合是否为空System.out.println(list.isEmpty());System.out.println(list);}
}
java">package com.itheima.day04;import java.util.ArrayList;public class List列表集合 {public static void main(String[] args) {// 创建List,泛型只能使用引用数据类型,不能使用任何的基本数据类型ArrayList<Integer> list1 = new ArrayList<Integer>();// 新增list1.add(11);list1.add(33);list1.add(22);System.out.println(list1);// 查看System.out.println(list1.isEmpty());System.out.println(list1.contains(22));System.out.println(list1.contains(99));System.out.println(list1.size());System.out.println("-----------------------");// 迭代for (Integer tmp : list1) {System.out.println(tmp);}list1.forEach(tmp -> System.out.println(tmp));for (int i = 0; i < list1.size(); i++) {System.out.println(list1.get(i));}System.out.println("-----------------------");// 删除
// int removeValue = list1.remove(1);boolean removeValue = list1.remove(Integer.valueOf(11));System.out.println(removeValue);list1.clear();System.out.println(list1);}
}
需求:
- 定义一个学生类, 属性为姓名和年龄.
- 创建List集合(linkedList), 用来存储学生对象.
- 往List集合中, 添加3个学生的信息. (演示队列的特性)
- 遍历List集合.
java">package com.itheima.list单列集合;import java.util.Comparator;
import java.util.LinkedList;public class Test02_LinkedList {public static void main(String[] args) {//1. 创建 LinkedList 对象LinkedList<Student> linkedList = new LinkedList<>();//2. 执行操作: 主要演示 与队列相关的操作// 2.1 添加数据: 单端队列linkedList.offer(new Student("张三",20,"北京"));linkedList.offer(new Student("李四",18,"上海"));linkedList.offer(new Student("王五",25,"广州"));// 2.2 取出元素// Student s1 = linkedList.poll();// Student s2 = linkedList.poll();// Student s3 = linkedList.poll();// System.out.println(s1);// System.out.println(s2);// System.out.println(s3);// 2.3 对列表中数据进行排序: 要求 按照 对象中 age进行排序linkedList.sort(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o2.getAge().compareTo(o1.getAge());}});System.out.println(linkedList);}}
java">package com.itheima.day04.list列表案例;import java.util.Comparator;
import java.util.LinkedList;public class ListTest {public static void main(String[] args) {LinkedList<Student> stuList = new LinkedList<>();// 从尾部添加元素stuList.offer(new Student("b",20));stuList.offer(new Student("a",18));stuList.offer(new Student("c",23));System.out.println(stuList);// 排序stuList.sort(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {// 按年龄降序
// return o2.getAge() - o1.getAge();// 按年龄升序return o1.getAge() - o2.getAge();}});// lambda表达式的形式stuList.sort((o1,o2) -> o2.getAge() - o1.getAge());System.out.println(stuList);// 从头部取出元素System.out.println(stuList.poll());System.out.println(stuList);}
}
1.2 常见的数据结构(了解)
数据结构是计算机存储, 组织数据的方式. 它是指相互之间存在一种或多种特定关系的数据元素的集合. 通常情况下, 精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关.
大白话理解:
数据结构指的就是数据的组织方式.
线性数据结构: 线性结构是一个有序数据元素的集合
常用的线性数据结构:
1- 栈
2- 队列
3- 数组
4- 链表
- 栈: 先进后出
- 队列: 先进先出
- 数组: 连续的内存空间
在添加和保存数据的时候, 只能在指定位置下添加数据, 添加和删除的数据效率低一些, 但是其具备高效随机读写的能力特点: 插入和删除效率低连续内存,大小固定,无法动态扩展可以根据下标随机访问,查找效率高弊端: 增删慢需要有一块连续内存空间, 对内存使用率不高
- 链表: 不是连续的内存空间, 无固定大小
好处: 对内存使用更加合理, 节省空间增删快无固定大小, 可以扩展
弊端: 随机查询的效率低, 因为链接必须从头一步一步检索, 只有知道上一个位置, 才能知道下一个位置
1.3 Set集合
Set集合是Collection集合的子体系, 它的元素特点是无序, 唯一.
注意:
- Set集合是一个接口, 所以不能通过new的方式直接创建它的对象.
- Set集合中没有带索引的方法, 所以不能通过普通for循环遍历.
- Set集合的常用子类主要是HashSet集合
- 只允许存放相同类型的元素
HashSet集合:
1.底层数据结构是哈希表.
2.对集合的迭代顺序不做任何保证, 也就是说不保证元素的存取顺序一致.
3.没有带索引的方法, 所以不能通过普通for循环遍历.
4.由于是Set集合, 所以是不包含重复元素的集合.总结:
HashSet集合的特点是: 无序, 唯一, 元素无索引, 它的底层数据结构是: 哈希表. 扩展: 所谓的哈希值指的是JDK根据对象的地址, 或者字符串, 或者数字 算出来的int类型的数值.
需求1:
-
1 定义HashSet集合, 存储字符串"hello", “world”, “java”, “world”
-
2 遍历HashSet集合, 打印每一个元素值, 并观察程序的运行结果.
java">package com.itheima.set单列集合;import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;public class Test01_set {public static void main(String[] args) {//1. 创建Set集合对象: 无序 去重Set<String> set = new HashSet<>();//2. 执行相关的操作:// 2.1 添加元素set.add("hello");set.add("world");set.add("Hadoop");set.add("spark");set.add("Hadoop");set.add("world");System.out.println(set);// 2.2 获取元素的长度int size = set.size();System.out.println(size);// 2.3 判断某个元素是否在set集合中boolean flag = set.contains("spark");System.out.println(flag);// 2.4 遍历set集合:System.out.println("--------------");// 增强for循环for (String e : set) {System.out.println(e);}System.out.println("--------------");// 迭代器处理Iterator<String> iterator = set.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}}
}
需求2:
-
1 定义学生类, 属性为姓名和年龄.
-
2 创建HashSet集合, 用来存储学生对象, 并往其中添加3个学生的信息.
-
3 遍历集合, 并把结果打印到控制台上.
java">package com.itheima.collection;import java.util.Objects;public class Student {public Student() {}public Student(String name, Integer age) {this.name = name;this.age = age;}private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return Objects.equals(name, student.name) &&Objects.equals(age, student.age);}// 在 set集合中, 如果放置的是对象 要想判断对象是否一致, 底层会调用 hashCode 方法, 基于这个方法判断 是否一致// 此方法默认返回当前这个地址值的hash值, 重写后 要求其返回数据的hash值@Overridepublic int hashCode() {return Objects.hash(name, age);}
}package com.itheima.collection;import java.util.HashSet;
import java.util.Iterator;public class Demo04_HashSetStudent {public static void main(String[] args) {//1. 创建 HashSet集合HashSet<Student> set = new HashSet<>(); // 去重 无序//2. 添加元素set.add(new Student("张三",20));set.add(new Student("李四",22));set.add(new Student("王五",25));set.add(new Student("李四",22));//3. 遍历打印for (Student student : set) {System.out.println(student);}}
}
注意: 如果hashset中放置的是对象, 判断数据是否相同的时候, 需要在对象中重写 equals 和 hashCode
1.4 哈希表
-
JDK8以前, 底层采用数组 + 链表的形式实现, 可以理解为: 一个元素为链表的数组.
-
JDK8以后, 在长度比较长的时候, 底层实现了优化.
图解
解释:
1."hello"的哈希值是99162322
2."world"的哈希值是113318802
3."java"的哈希值是3254818
4."world"的哈希值是113318802
5."通话"的哈希值是1179395
6."重地"的哈希值是1179395
7.存储的时候, 会将上述的哈希值和16进行取余操作, 然后根据余数值进行存储. 在每个槽下, 都是基于链表的方式来存储的
2、双列集合
Map集合是双列集合的顶层接口, 它是用来存储键值对对象的, 其中键具有唯一性, 而值是可以重复的. 类似于Python中字典
即: Map集合的数据结构只针对于键有效.
public interface Map<K, V> //K: 键的类型, V: 值的类型.
例如:
•itheima001 刘亦菲
•itheima002 赵丽颖
•itheima003 高圆圆
因为Map是接口, 不能通过new关键字直接创建它的对象, 我们可以通过多态的形式, 创建其子类对象. 从而实现创建Map集合对象的这个需求.
注意: Map集合的常用子类是: HashMap
常用的成员方法:
方法名 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
Map集合的获取功能:
方法名 | 说明 |
---|---|
V get(Object key) | 根据键获取值 |
Set keySet() | 获取所有键的集合 |
Collection values() | 获取所有值的集合 |
示例: 普通数据
package com.itheima.day04;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class Map测试 {public static void main(String[] args) {HashMap<String, String> map1 = new HashMap<>();map1.put("1001","张三");map1.put("1003","李四");map1.put("1002","王五");System.out.println(map1);System.out.println(map1.containsKey("1001"));System.out.println(map1.containsKey("1009"));System.out.println(map1.containsValue("李四"));System.out.println(map1.containsValue("hello"));System.out.println(map1.isEmpty());System.out.println(map1.size());System.out.println(map1.get("1001"));System.out.println(map1.get("1009")); // 如果对应的key不存在,返回nullSystem.out.println(map1.remove("1001"));System.out.println(map1.remove("1003", "李四11111"));System.out.println(map1);System.out.println(map1.remove("1003", "李四"));HashMap<String, String> map2 = new HashMap<>();map2.put("1001","张三");map2.put("1003","李四");map2.put("1002","王五");Set<String> keys = map2.keySet();System.out.println(keys);Collection<String> values = map2.values();System.out.println(values);// map的遍历map2.forEach((key,value) -> System.out.println(key+value));Set<Map.Entry<String, String>> entries = map2.entrySet();for (Map.Entry<String, String> entry : entries) {String key = entry.getKey();String value = entry.getValue();System.out.println(key+"="+value);}}
}
示例2: 放置对象
java">package com.itheima.map;import java.util.Objects;public class Teacher {public Teacher() {}public Teacher(String name, Integer age, String address) {this.name = name;this.age = age;this.address = address;}private String name;private Integer age;private String address;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Teacher{" +"name='" + name + '\'' +", age=" + age +", address='" + address + '\'' +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Teacher teacher = (Teacher) o;return Objects.equals(name, teacher.name) &&Objects.equals(age, teacher.age) &&Objects.equals(address, teacher.address);}@Overridepublic int hashCode() {return Objects.hash(name, age, address);}
}package com.itheima.map;import java.util.HashMap;public class Demo06_HashMap {public static void main(String[] args) {//1. 创建HashMap对象HashMap<String, Teacher> map = new HashMap<>();// 2.执行相关操作map.put("001",new Teacher("LAO WANG",28,"广州"));map.put("001",new Teacher("LAO ZHANG",28,"上海"));map.put("001",new Teacher("LAO LI",28,"深圳"));System.out.println(map);// 将 对象 作为keyHashMap<Teacher, String> map1 = new HashMap<>();map1.put(new Teacher("LAO WANG",28,"广州"),"001");map1.put(new Teacher("LAO WANG",28,"广州"),"002");map1.put(new Teacher("LAO WANG",28,"广州"),"003");System.out.println(map1);}
}
3、Collections集合工具类
Collections类是针对集合操作的工具类.
- 常用方法
方法名 | 说明 |
---|---|
public static void sort(List list) | 将指定的列表按升序排序 |
public static void reverse(List<?> list) | 反转指定列表中元素的顺序 |
public static void shuffle(List<?> list) | 使用默认的随机源随机排列指定的列表 |
示例: 演示相关方法
java">package com.itheima.集合工具类;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;public class Test01_collections {public static void main(String[] args) {// 1. 创建一个集合:ArrayList<String> list = new ArrayList<>();//2. 添加数据list.add("hadoop");list.add("hive");list.add("spark");list.add("oozie");list.add("flink");list.add("java");list.add("zookeeper");list.add("datax");System.out.println(list);//3. 执行一些相关的操作:// 3.1 执行随机打散操作Collections.shuffle(list);System.out.println(list);// 3.2 执行反转操作Collections.reverse(list);System.out.println(list);// 3.3 执行 排序操作Collections.sort(list);System.out.println(list);// Collections.reverse(list);// System.out.println(list);Collections.sort(list, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return o2.compareTo(o1);}});System.out.println(list);}}
对象比较处理:
package com.itheima.集合工具类;import java.util.Objects;public class Student {public Student() {}public Student(String name, Integer age) {this.name = name;this.age = age;}private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return Objects.equals(name, student.name) &&Objects.equals(age, student.age);}// 在 set集合中, 如果放置的是对象 要想判断对象是否一致, 底层会调用 hashCode 方法, 基于这个方法判断 是否一致// 此方法默认返回当前这个地址值的hash值, 重写后 要求其返回数据的hash值@Overridepublic int hashCode() {return Objects.hash(name, age);}
}package com.itheima.集合工具类;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;public class Demo08_collections {public static void main(String[] args) {//1. 构建一个集合: 类型为对象ArrayList<Student> list1 = new ArrayList<>();list1.add(new Student("张三",20));list1.add(new Student("张三",28));list1.add(new Student("张三",26));list1.add(new Student("张三",29));list1.add(new Student("张三",32));// 2. 执行操作// 对 数据进行排序, 要求age排序Collections.sort(list1, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge().compareTo(o2.getAge());}});System.out.println(list1);// 取年龄最大值Student student = Collections.max(list1, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge().compareTo(o2.getAge());}});System.out.println(student);// 取年龄最大值student = Collections.min(list1, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge().compareTo(o2.getAge());}});System.out.println(student);}
}
四、(掌握)Lambda表达式
Lambda表达式本身就是匿名方法(代码块),就是将方法(代码块)赋值给一个变量,lambda的类型都是一个接口。
如何出现的呢?以下演化过程
-
阶段一: Java变量赋值
-
阶段二: 将一个方法或者(代码块)赋值给变量
- 阶段三: 在 java8之后利用 lambda 特性,就可以做到
- 阶段四: 更优雅和简洁的实现
将方法(代码块)赋值给了一个变量,就是一个 lambda 表达式。
1、体验Lambda表达式
需求:
-
1- 已知接口Animal中有一个抽象方法eat()
-
2- 在测试类AnimalTest中定义show(Animal an)方法, 实现调用Animal#eat()方法.
-
3- 并在main方法中, 调用AnimalTest#show()方法.
java">package com.itheima.lambda;public class Demo10_lambda表达式初体验 {public static void main(String[] args) {//1. 创建Animal的对象Animal cat = new Animal() {@Overridepublic void eat() {System.out.println("猫吃鱼");}};// 调用 方法execute(cat);// ==========================================// 采用 lambda 表达式的方案Animal animal = () -> System.out.println("狗爱吃骨头");execute(animal);}public static void execute(Animal animal){animal.eat();}}
java">package com.itheima.day04.lambda表达式;public class Lambda表达式 {public static void main(String[] args) {// 匿名内部类Animal animal = new Animal(){@Overridepublic void eat(String food) {System.out.println("动物吃"+food);}};animal.eat("肠粉");/*格式一:如果形参个数>=2,必须要有小括号如果代码的行数>=2,必须要有大括号格式二:形参的数据类型全部都可以省略如果代码的行数只有一行,可以省略大括号格式三:如果形参有且只有一个,那么可以省略形参外面的小括号*/// Lambda表达式:格式一Animal animal1 = (String food) -> {System.out.println("动物吃"+food);};animal1.eat("辣条");// Lambda表达式:格式二Animal animal2 = (food) -> System.out.println("动物吃"+food);animal2.eat("辣条2");// Lambda表达式:格式三Animal animal3 = food -> System.out.println("动物吃"+food);animal3.eat("辣条3");}
}
2、Lambda表达式的标准格式
格式:
(形式参数) -> {代码块}
• 形式参数:如果有多个参数,参数之间用逗号隔开, 如果没有参数,留空即可
• ->:由英文中画线和大于符号组成,固定写法。代表指向动作
• 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
• 组成Lambda表达式的三要素:形式参数,箭头,代码块
Lambda使用的前提条件: 有一个接口, 且接口中有且仅有一个抽象方法.
案例一: 无参无返回值抽象方法
定义一个接口(Eatable),里面定义一个抽象方法:void eat();
定义一个测试类(EatableDemo),在测试类中提供两个方法一个方法是:useEatable(Eatable e)一个方法是主方法,在主方法中调用useEatable方法
代码实现:
java">package com.itheima.lambda;public class Test02_eatable {public static void main(String[] args) {// 匿名内部类// Eatable e = new Eatable() {// @Override// public void eat() {// System.out.println("吃东西...");// }// };// lambda表达式写法: 相当于重写 接口 eat 方法Eatable e = () -> {System.out.println("吃东西...");};useEatable(e);}public static void useEatable(Eatable e){e.eat();}}
案例二: 有参无返回值抽象方法的练习
定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);
定义一个测试类(FlyableDemo),在测试类中提供两个方法一个方法是:useFlyable(Flyable f)一个方法是主方法,在主方法中调用useFlyable方法
代码实现:
java">package com.itheima.lambda;public class Test03_Flyable {public static void main(String[] args) {// Flyable f = (String s) -> {// System.out.println(s +"要飞");// };// 省略写法:// 省略1: 当 {} 中代码块只有一行的时候, 可以省略 {} 以及 分号// Flyable f = (String s) -> System.out.println(s +"要飞");// 省略2: () 里面的参数类型 可以不写, 如果有多个参数, 要省略一起省略//Flyable f = (s) -> System.out.println(s +"要飞");// 省略3: () 里面只有一个参数, 可以省略 小括号//Flyable f = s -> System.out.println(s +"要飞");//useFlyable(f);// 合并在一起:useFlyable(s -> System.out.println(s +"要飞"));}public static void useFlyable(Flyable f){f.fly("老张");}}
案例三: 有参有返回值抽象方法的练习
定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);
定义一个测试类(AddableDemo),在测试类中提供两个方法一个方法是:useAddable(Addable a)一个方法是主方法,在主方法中调用useAddable方法
java">package com.itheima.lambda;public class Test04_Addable {public static void main(String[] args) {// Addable a = (int x,int y) -> {// return x + y;// };// 省略操作:Addable a = (x,y) -> x + y;useAddable(a);}public static void useAddable(Addable a){int sum = a.add(3, 5);System.out.println(sum);}
}
案例四: 模拟一下 Spark中 map方法: 传入一个 返回一个操作
java">package com.itheima.lambda;public interface SparkRDD<IN,OUT> {public OUT map(IN data);
}package com.itheima.lambda;import java.util.Arrays;
import java.util.List;public class Demo14_SparkRDDTest {public static void main(String[] args) {List<String> list = map(data -> Arrays.asList(data.split(" "))); // 仅仅是在定义处理数据的逻辑System.out.println(list);}public static List<String> map(SparkRDD<String,List<String>> rdd){return rdd.map("hello world spark hadoop");}}
3、Lambda省略模式
规则:
- 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
- 如果参数有且仅有一个,那么小括号可以省略
- 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
4、Lambda表达式和匿名内部类的区别
-
所需类型不同
-
匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
-
Lambda表达式:只能是接口
-
-
使用限制不同
- 如果接口中有且****仅有一个抽象方法****,可以使用Lambda表达式,也可以使用匿名内部类
- 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
-
实现原理不同
- 匿名内部类:编译之后,产生一个单独的.class字节码文件
- Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成。
五、JDBC协议
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成。
JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。 今天我们使用的是mysql的驱动mysql-connector-java-5.1.37-bin.jar
JDBC规范(掌握四个核心对象):
-
1 DriverManager:用于注册驱动
-
2 Connection: 表示与数据库创建的连接
-
3 Statement: 操作数据库sql语句的对象
-
4 ResultSet: 结果集或一张虚拟表
1、JDBC原理
Java提供访问数据库规范称为JDBC,而生产厂商提供规范的实现类称为驱动。
**JDBC的核心作用是为了实现代码程序与具体数据库产品解耦。**JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。
2、JDBC入门案例
-
1- 在Java的项目中, 创建一个 lib的目录
-
2- 将资料中提供的Mysql驱动jar包, 添加到lib目录下
-
3- 让整个项目加载到当前这个依赖驱动jar包
2.1 查询表中数据
准备工作: 打开MySQL, 创建表, 添加一些测试数据
create database day04_jdbc char set 'utf8';
use day04_jdbc;
create table stu(id int primary key,name varchar(20),age int,address varchar(20)
);insert into stu (id,name,age,address) values(1,'张三',20,'北京');
insert into stu (id,name,age,address) values(2,'李四',18,'上海');
insert into stu (id,name,age,address) values(3,'王五',22,'广州');
insert into stu (id,name,age,address) values(4,'赵六',28,'深圳');
insert into stu (id,name,age,address) values(5,'田七',23,'杭州');
代码编写:
JDBC使用六大步: 1- 注册驱动 : Class.forName("com.mysql.jdbc.Driver");2- 获取连接对象 :Connection conn = DriverManager.getConnection(url,username,password)3- 根据连接对象, 创建语句执行平台方式一: Statement stat1 = conn.createStatement()方式二: Statement stat2 = conn.prepareStatement(String sql)4- 执行SQL针对方式一的执行平台: Boolean flag = stat1.execute(SQL): 执行 增 删 改 返回false, 如果执行查询返回trueint i = stat1.executeUpdate(SQL): 返回值表示影响了多少行ResultSet rs = stat1.executeQuery(SQL): 表示返回的结果集对象, 此对象为二维的表Boolean flag = rs.next(); 指向下一行数据, 如果没有 返回falseXxx 变量 = rs.getXxx('字段'); 获取指定列的数据, Xxx表示此列的数据类型针对方式二的执行平台: stat2.setXxx(int I, Xxx data); 为SQL中对应参数赋值 (后面讲的时候说)Boolean flag = stat2.execute(): 执行 增 删 改 返回false, 如果执行查询返回trueint i = stat2.executeUpdate(): 返回值表示影响了多少行ResultSet rs = stat2.executeQuery(): 表示返回的结果集对象, 此对象为二维的表Boolean flag = rs.next(); 指向下一行数据, 如果没有 返回falseXxx 变量 = rs.getXxx('字段'); 获取指定列的数据, Xxx表示此列的数据类型5- 处理结果集: 增 删 改不需要处理, 简单打印一下返回的受影响行即可查询: 对ResultSet结果集 进行遍历获取每一行, 每一列的数据6- 释放资源:所有涉及到对象, 只有有close的方法, 都需要关闭, 关闭资源遵循从后往前关闭
代码实现:
java">package com.itheima.day04;import java.sql.*;public class JDBC操作案例 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1- 注册驱动Class.forName("com.mysql.jdbc.Driver");// 2- 获取数据库连接String url = "jdbc:mysql://192.168.88.166:3306/day04_jdbc?useUnicode=true&characterEncoding=utf8&useSSL=false";Connection conn = DriverManager.getConnection(url, "root", "123456");// 3- 获取执行SQL语句的对象Statement statement = conn.createStatement();// 4- 执行SQLString sql = "select * from stu";ResultSet rs = statement.executeQuery(sql);System.out.println(rs);// 5- 处理返回结果while (rs.next()){int id = rs.getInt("id");String name = rs.getString("name");int age = rs.getInt("age");String address = rs.getString("address");System.out.println(id+","+name+","+age+","+address);}// 6- 释放资源rs.close();statement.close();conn.close();}
}
2.2 如何添加数据
java">package com.itheima.day04;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class JDBC操作案例新增 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1- 注册驱动。通过反射创建Class.forName("com.mysql.jdbc.Driver");// 2- 获取数据库连接String url = "jdbc:mysql://192.168.88.166:3306/day04_jdbc?useUnicode=true&characterEncoding=utf8&useSSL=false";Connection conn = DriverManager.getConnection(url, "root", "123456");// 3- 获取SQL执行对象Statement statement = conn.createStatement();// 4- 执行插入语句String sql = "insert into stu (id,name,age,address) values(6,'王六',22,'深圳')";// 表示影响的数据条数int result = statement.executeUpdate(sql);System.out.println(result);// 5- 释放资源statement.close();conn.close();}
}
2.3 如何修改数据
java">package com.itheima.day04;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class JDBC操作案例更新 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1- 注册驱动。通过反射创建Class.forName("com.mysql.jdbc.Driver");// 2- 获取数据库连接String url = "jdbc:mysql://192.168.88.166:3306/day04_jdbc?useUnicode=true&characterEncoding=utf8&useSSL=false";Connection conn = DriverManager.getConnection(url, "root", "123456");// 3- 获取SQL执行对象Statement statement = conn.createStatement();// 4- 执行更新语句String sql = "update stu set name='周六',age=99 where id=6";// 表示影响的数据条数int result = statement.executeUpdate(sql);System.out.println(result);// 5- 释放资源statement.close();conn.close();}
}
2.4 如何删除数据
java">package com.itheima.day04;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class JDBC操作案例删除 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1- 注册驱动。通过反射创建Class.forName("com.mysql.jdbc.Driver");// 2- 获取数据库连接String url = "jdbc:mysql://192.168.88.166:3306/day04_jdbc?useUnicode=true&characterEncoding=utf8&useSSL=false";Connection conn = DriverManager.getConnection(url, "root", "123456");// 3- 获取SQL执行对象Statement statement = conn.createStatement();// 4- 执行删除语句String sql = "delete from stu where id=6";// 表示影响的数据条数int result = statement.executeUpdate(sql);System.out.println(result);// 5- 释放资源statement.close();conn.close();}
}
说明:
1- 完成 每个集合的常用API的使用, 建议可以通过查看API帮助文档来操作2- 完成Lambda表达式的案例演示: 有参数 无参 有返回值 五返回值 (尝试使用省略的方式来写)3- 完成JDBC的操作的CURD 4- 将之前的登录案例, 尝试连接数据库实现: 在数据库中创建一个表, 有用户名 和 密码. 让用户输入 , 输入后和系统的用户名和密码进行比对, 如果成功, 返回登录成功, 否则登录失败