JAVA学习笔记基础篇_02
------------恢复内容开始------------
# java高级应用1.补充
当方法中不存在与对象相关的方法时 比如 直接的数字计算 输出 等 都可以写成静态方法 集合成一个工具类
1.类变量与类方法(静态变量 / 静态方法)
也就是记录变量和方法的使用次数 , 每次随着类的生成而生成 随着类的消失而消失?
static 和 final ? 静态变量 (打点计时器) final 定义常量.
类变量 又叫静态属性, 是该类所有的对象共享的变量,任何一个该类的对象请访问它时,取出来的值都是一样的,同样 任何变量去修改时,也是修改的同一个值.
特点:-
根据版本的不同
-
static 在java7以前 在方法区的静态域中
-
static 在java7及以后在堆中 随着类的生成 生成一个class对象,
内存区域:
- 不管static在哪里 静态变量在同类中所有对象共享
- 在类加载的时候就生成了.
非受检的可以不处理
但是受检的必须处理
Throwable 是所有异常的父类
子类是error 错误(jvm问题) 会系统崩溃
exception 异常 不一定崩溃
按受不受检可分为:
分有非受检异常(unchecked ) 和受检异常 (checked)
error 和 exception 的runtimeException的子类 包括常见的: 算术异常 类异常 空指针异常
ArrayList底层详解:
- ArrayList 底层是通过维护了一个Object数组 elementData 实现的,特点是查询速度快,增加删除慢
- ArrayList 使用无参构造函数创建对象时,初始容量是0 ,第一次添加默认的容量是10,当长度不够时,自动增长0.5倍,也就是原来数组长度的1.5倍
- 如果使用指定大小的构造器 扩容会直接是elementData为1.5倍
1.Object[] 意味着什么都能放进去
添加:b指向前一个的a a的next 指向b 同时 b的next指向c c的prev指向b
删除:a的next指向c c的prev指向a b被删除
改查
自建双链表CRUD
增删改查的实现 还可以封装起来到Node里 注意每次(头 尾)增改
还有遍历后 first 和 last 的指针回溯问题
package com.javastudy;
import javax.xml.soap.Node;
/**
* @Author: qianl
* @Date: 2022/12/10 10:51
* @Description: item 类型是Object
*/
public class Node_ {
public static void main(String[] args) {
Node01 one = new Node01("第一个");
Node01 two = new Node01("第二个");
Node01 there = new Node01("第三个");
//双向链表
//首节点
one.next = two;
//中间节点
two.prev = one;
two.next = there;
//尾节点
there.prev = two;
Node01 first = one;// 指向头节点
Node01 last = there;//指向尾节点
//从头到尾遍历
while (true) {
//一开始 first = one;
//最后 first 指向了 there的next == null
if (first == null) {
break;
}
//输出 one 的内容
System.out.println(first);
//first = one的next
first = first.next;
}
//从尾到头遍历
while (true){
if (last == null){
break;
}
System.out.println(last);
last=last.prev;
}
//添加数据
Node01 five = new Node01("添加第五个在尾");
//尾添加
there.next = five;
five.prev = there;
last = five;
Node01 zero = new Node01("添加第0个在头");
//头添加
one.prev = zero;
zero.next = one;
first = zero;
Node01 four = new Node01("中间添加第四个");
//中间添加
there.next =four;
four.prev =there;
four.next =five;
five.prev =four;
//遍历
while (true){
if (first==null){
break;
}
System.out.println(first);
first = first.next;
}
//删除:
//删除第四个
there.next = five;
five.prev = there;
//遍历
System.out.println("====删除后====");
//重新指针:
first = zero;
while (true){
if (first==null){
break;
}
System.out.println(first);
first = first.next;
}
}
}
class Node01 {
private Object item;//存储内容
public Node01 next;//指向下一个节点
public Node01 prev;//指向上一个节点
private int size = 0;
public Node01(Object item) {
this.item = item;
}
@Override
public String toString() {
return "Node_{" +
"item=" + item +
'}';
}
}
LinkedList的CRUD和常用方法:
- 删除remove 增加add 都有专门的 堆first 和last的操作 removeFirst, addLast等
- set方法 修改 使用(index,element)来操作 单独查看首尾
- get方法 获得 查看 使用index 或者单独查看首尾
- poll() 投票 是出栈操作 从头开始 然后 依次出栈
- push() 推动 入栈操作 从头开始 依次入栈
- offer() 提供 查询是否有什么数 返回类型: true
package com.javastudy.linkedList_;
import java.util.LinkedList;
import java.util.List;
/**
* @Author: qianl
* @Date: 2022/12/10 13:02
* @Description:
*/
public class LinkedList_ {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add("第一个");
linkedList.add("第二个");
linkedList.add("第三个");
linkedList.add("第五个");
for (Object o : linkedList) {
System.out.println(o);
}
//增首尾(有专门的方法)
linkedList.addFirst("第0个");
linkedList.addLast("第六个");
for (Object o : linkedList) {
System.out.println(o);
}
//删除
linkedList.remove("第五个");
//删除首尾
linkedList.removeFirst();
linkedList.removeLast();
System.out.println(linkedList.size());
System.out.println("======");
//获取第几个 首尾元素
System.out.println(linkedList.get(1));
System.out.println(linkedList.getFirst());
System.out.println(linkedList.getLast());
//peek 窥探 查看?
System.out.println(linkedList.peek());
System.out.println(linkedList.peek());
//poll 投票 其实就是 弹夹弹出元素 出栈一样 返回被弹出的数量
// System.out.println(linkedList.poll());
// System.out.println(linkedList.poll());
linkedList.set(1,"我更改了第二个");
System.out.println("====");
for (Object o : linkedList) {
System.out.println(o);
}
//?
System.out.println(linkedList.pop());
System.out.println(linkedList.indexOf("第三个"));
//1
// offer 提供
System.out.println(linkedList.offer("第三个"));
//true
System.out.println("======");
for (Object o : linkedList) {
System.out.println(o);
}
//push 推 推动 ?
linkedList.push("第三个");
System.out.println("======");
for (Object o : linkedList) {
System.out.println(o);
}
/*======
我更改了第二个
第三个
第三个
======
第三个
我更改了第二个
第三个
第三个*/
}
}
LinkedList解析:
//无参方法
public LinkedList() {
}
//此时 first = null; last = null;
//指向add()后
public boolean add(E e) {
linkLast(e);
return true;
}
//默认范围
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null); // (null,e,null)
//last = 这个节点
last = newNode;
if (l == null) // √ first = newNode;
first = newNode;
else
l.next = newNode;
size++; //长度
modCount++; //模式记数
}
//所以第一次跑完 就是 first = Node01 (null,e,null) = last
//第二次 l = last = Node01
// Node01.next = Node02
// first = Node01(null,e,Node02)
// Node02(Node01,e,null) =last
ArrayList 和LinkedList 的比较
子类 | 底层结构 | 增删效率 | 改查效率 | Index |
---|---|---|---|---|
ArrayList | 可变数组(存储空间在一起) | 较低 数组扩容 | 较高 | 可以使用下标 |
LinkedList | 双向链表(存储空间不一定在一起) | 较高, 通过链表追加 | 较低 | 可以使用下标 |
使用场景
-
增删多使用ArrayList
-
改查多 使用LinkedList
-
一般 程序都是查询 使用ArrayList
-
也可以灵活运用 一个模块使用ArrayList 一个模块使用LinkedList
双链表:
1.1双向链表
相较单链表,双向链表除了data与next域,还多了一个pre域用于表示每个节点的前一个元素。这样做给双向链表带来了很多优势:
-
单向链表查找的方向只能是一个方向,而双向链表可以向前或者向后查找;
-
单链表如果想要实现删除操作,需要找到待删除节点的前一个节点。而双向链表可以实现自我删除。
双向链表结构示意图如下:
1.2 双向链表实现思路
与单链表实现类似,交集部分不再赘述,详情可参考文章:Java数据结构:单链表的实现与面试题汇总
遍历:
与单链表遍历方式一样,同时,双向链表可以支持向前和向后两种查找方式
添加:
添加到末尾
先找到双向链表最后一个节点
cur.next = newNode;
newNode.pre = cur;
按照no顺序添加
”先判断该链表是否为空,如果为空则直接添加
如果不为空则继续处理
根据no遍历链表,找到合适的位置
newNode.next = cur.next;
cur.next = newNode;
newNode.pre = cur;
修改操作与单链表实现步骤一致“
删除操作:
双向链表可以实现自我删除
直接找到待删除的节点
cur.pre.next = cur.next;
cur.next.pre = cur.pre;
需要特别注意是否为最后一个元素,如果为最后一个元素,cur.next为null,此时使用cur.next.pre会出现空指针异常,所以,如果为最后一个元素,则该步骤可以省略,cur.next为null即可。
以删除红色的2号节点为例:
1.3双向链表实例:
Java数据结构:双向链表的实现-阿里云开发者社区 (aliyun.com)
Set接口:
基本特点:
- 无序(没有index) 添加和取出的顺序不一致
- 不允许重复元素, 至多只有一个null
- JDK中的实现类有:
- 重点是HashSet 和TreeSet子类
compact1, compact2, compact3
java.util
Interface Set<E>
Type Parameters:
E - the type of elements maintained by this set
All Superinterfaces:
Collection<E>, Iterable<E>
All Known Subinterfaces:
NavigableSet<E>, SortedSet<E>
All Known Implementing Classes:
AbstractSet, ConcurrentHashMap.KeySetView, ConcurrentSkipListSet, CopyOnWriteArraySet, EnumSet, "HashSet", JobStateReasons, LinkedHashSet, "TreeSet"
Set方法:
注意没有索引 所以不能使用for循环遍历
底层是数组加链表
** //1.不能重复 一个null
//2.无序(存入取出顺序不一致)
//3.取出顺序是固定的**
package com.javastudy.Set_;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* @Author: qianl
* @Date: 2022/12/11 03:02
* @Description:
*/
public class SetMethod_ {
public static void main(String[] args) {
//1.不能重复 一个null
//2.无序(存入取出顺序不一致)
//3.取出顺序是固定的
Set set = new HashSet();
set.add("one");
set.add("two");
set.add("there");
set.add("four");
set.add(null);
set.add(null);//添加重复元素 不会重复添加
set.add(null);
//可以看见输出和输入顺序不一致
System.out.println("set" + set);
//set[null, four, one, there, two]
//删除 null值
set.remove(null);
//1.遍历方法: 迭代器
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
//2,增强for for - each
for (Object o : set) {
System.out.println(o);
}
//for循环 不能通过索引进行
/* for (int i = 0; i < set.size(); i++) {
}*/
}
}
HashSet:
- 实现了Set接口.
- 本质是一个hashMap (Map接口 键值对) 但是Collection中是 值
- 可以存放null值, 但是只能有一个null
- HashSet不保证元素是有序的,取决于hash后,再索引的结果 存取顺序不一定一致
- 但取出顺序固定
- 不能有重复元素/对象 Set接口的特点
- 本质是(数组 + 链表 + 红黑树)
结构:
java可以操作数据库, db.Properties 记录DB的用户名和密码 然后操作密码什么的时候 就使用db.Properties 来进行修改 Properties 还可以用于 从xxx.properties文中,加载数据到Properties类对象.
属性文件a.properties如下:
name=root
pass=liu
key=value
读取a.properties属性列表,与生成属性文件b.properties。代码如下:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Properties;
public class PropertyTest {
public static void main(String[] args) {
Properties prop = new Properties();
try{
//读取属性文件a.properties
InputStream in = new BufferedInputStream (new FileInputStream("a.properties"));
prop.load(in); ///加载属性列表
Iterator<String> it=prop.stringPropertyNames().iterator();
while(it.hasNext()){
String key=it.next();
System.out.println(key+":"+prop.getProperty(key));
}
in.close();
///保存属性到b.properties文件
FileOutputStream oFile = new FileOutputStream("b.properties", true);//true表示追加打开
prop.setProperty("phone", "10086");
prop.store(oFile, "The New properties file");
oFile.close();
}
catch(Exception e){
System.out.println(e);
}
}
}
TreeMap:
使用无参构造器是无序的
需要传入比较器:
同TreeSet
集合\映射总结:
选择集合实现类:
如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
尽量返回接口而非实际的类型,如返回List而非 ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。
尽量写 Set set = new HashSet() // Map map = new TreeMap 需要时 只需要更改HashSet 就欧克了
Collections 工具类:
工具类方法01:
-
Collections 是一个操作Set List 和Map 等集合的工具类
-
Collections中 提供了一系列静态方法 对集合元素进行排序\ 查询和修改等操作,
-
排序操作(都是静态方法)
-
reverse(List) 反转List中元素的顺序
-
shuffle(List) 对List集合元素进行随机排序 (每次输出结果不一)
可以shuffle(List,rnd) rnd 是Random的随机数对象
-
sort(List) 根据元素的自然顺序对指定List 集合元素按升序排序
-
sort(List,Comparator) 根据指定的Comparator 产生的顺序 对List 集合元素进行自定义排序
-
swap(List int int ): 将指定list集合中的 i 处元素和 j 处元素进行交换 (index)
package com.javastudy.Map_;
import java.util.*;
/**
* @Author: qianl
* @Date: 2022/12/15 11:08
* @Description:
*/
public class Properties_ {
public static void main(String[] args) {
//1. Properties 继承 HashTale
//2. 可以通过 K-V 存放数据,当然 key value 都不能null
//增加
Properties properties = new Properties();
properties.put("001",1);//k-v
List arrayList = new ArrayList();
arrayList.add(new Test("001",1));
arrayList.add(new Test("002",2));
arrayList.add(new Test("003",3));
arrayList.add(new Test("004",4));
System.out.println(arrayList);
//[Test{name='001', age=1}, Test{name='002', age=2},
// Test{name='003', age=3}, Test{name='004', age=4}]
//1. 反转
Collections.reverse(arrayList);
System.out.println(arrayList);
//[Test{name='004', age=4}, Test{name='003', age=3},
// Test{name='002', age=2}, Test{name='001', age=1}]
//2. 随机排序 每次结果不一
Collections.shuffle(arrayList);
//使用迭代器 or For-Each
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.print(next+"\t");
}
System.out.println("\n"+"=====");
//3.1 使用元素的自然排序(升序) 不能是对象的 只能是String 之类的
//Collections.sort(arrayList);
//3.2 自定义排序 一个问题 假如不是以int类型进行 怎么处理
Collections.sort(arrayList, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
Test t1;
Test t2;
//1.先进行类型转换
t1 = (Test)o1;
t2 = (Test)o2;
return t1.getAge()- t2.getAge();
}
});
//需要重写比较方法
//com.recomastudy.Map_。无法将测试强制转换为java.lang.Comparable 报错
for (Object o : arrayList) {
System.out.print(o+"\t");
}
//Test{name='001', age=1} Test{name='002', age=2}
// Test{name='003', age=3} Test{name='004', age=4}
System.out.println("=======");
//4. swap(List int int ): 将指定list集合中的 i 处元素和 j 处元素进行交换
//指的是下标!!!
Collections.swap(arrayList,1,3);
System.out.println(arrayList);
//[Test{name='001', age=1}, Test{name='004', age=4},
// Test{name='003', age=3}, Test{name='002', age=2}]
}
}
class Test{
private String name;
private Integer age;
@Override
public String toString() {
return "Test{" +
"name='" + name + '\'' +
", age=" + 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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test test = (Test) o;
return Objects.equals(name, test.name) &&
Objects.equals(age, test.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public Test(String name, Integer age) {
this.name = name;
this.age = age;
}
}
工具类方法02:
-
Object max(Collection) 根据自然排序,返回给定集合中最大元素
-
Object max(Collection, Comparator) : 根据Comparator指定的顺序,给出最大元素
-
Object min(Collection)
-
Object min(Collection, Comparator) (比较器)
-
int frequency(Collection, Object) :返回指定集合中指定元素的出现次数; (频次,频率)
-
void copy(List dest,List src): 将src的内容复制到dest中;
//需要实际添加元素类型!! 给初始值 保证一定有空间 上面泛型没有定义元素 就使用Object 这样对象也能放进去
List vector= Arrays.asList( new Object[list.size()] );
//Arrays.asList 将数组变成List类型 转换期间不能使用List的方法 -
boolean replaceAll(List list ,Object oldVal, Object newVal): 使用新值 替换List对象中的所有旧值
Collections.replaceAll(vector,"Hello",null);//将Hello ---> null
就是要填入初始值 ,并使得大小与被复制的List.size() 一致
package com.javastudy;
import java.util.*;
/**
* @Author: qianl
* @Date: 2022/12/17 11:17
* @Description:
*/
public class Collections_ {
public static void main(String[] args) {
List list = new ArrayList();
list.add("Hello");
list.add("World");
list.add("Java");
//1. Object max(Collection) 根据自然排序,返回给定集合中最大元素
System.out.println(Collections.max(list));
//World
//2. Object max(Collection, Comparator) : 根据Comparator指定的顺序,给出最大元素
System.out.println(Collections.max(list, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
//根据长度 反向排序
return ((String)o2).length()-((String)o1).length();
}
}));
//Java
//3. Object min(Collection)
System.out.println(Collections.min(list));
//Hello
//4. Object min(Collection, Comparator) (比较器)
System.out.println(Collections.min(list, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
// //根据长度 反向排序
return ((String)o2).length()-((String)o1).length();
}
}));
//Hello
//5. int frequency(Collection, Object) :返回指定集合中指定元素的出现次数; (频次,频率)
System.out.println(Collections.frequency(list,"Hello"));
//1
//6. void copy(List dest,List src): 将src的内容复制到dest中;
//注意 要把长度加入 Collections.copy() 的源码
/* int srcSize = src.size();
如果srcSize大于dest.size,将会抛出异常
if (srcSize > dest.size())
throw new IndexOutOfBoundsException(“Source does not fit in dest”);
*/
//注意: 已经放进入 size 但是在运行中还是0
//List vector = new Vector(list.size());
//需要实际添加元素类型!! 给初始值 保证一定有空间 上面泛型没有定义元素 就使用Object 这样对象也能放进去
List vector= Arrays.asList(new Object[list.size()]);
//Arrays.asList 将数组变成List类型 转换期间不能使用List的方法
Collections.copy(vector,list);
//IndexOutOfBoundsException
for (Object o : vector) {
System.out.println(o);
}
/*Hello
World
Java
*/
//7. boolean replaceAll(List list ,Object oldVal, Object newVal): 使用新值 替换List对象中的所有旧值
Collections.replaceAll(vector,"Hello",null);//将Hello ---> null
for (Object o : vector) {
System.out.println(o);
}
/*null
World
Java*/
}
}
本章测试题:
题目1:
注意切片 subString();
package com.javastudy;
import javax.xml.soap.Node;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @Author: qianl
* @Date: 2022/12/17 12:28
* @Description:
*/
public class HomeWork01_ {
public static void main(String[] args) {
List<News> listNews = new ArrayList<News>();
//添加进List中
listNews.add(new News("新冠确诊病例超千万,数百万印度教徒赴恒河\"圣浴\"引民众担忧"));
listNews.add(new News("男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生"));
//遍历过程,标题进行处理 15字显示 后续的"...";
Iterator iterator = listNews.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
if (next instanceof News) {
News news = (News)next;
if (news.getTotal().length()>15){
//切片 单 15表示 从第15个字符开始 (0,15) --> 从0 到15
String str = news.getTotal().substring(0,15);
//beginIndex 和 endIndex
System.out.println(str+"...");
}else{
System.out.println(news);
}
}
}
//新冠确诊病例超千万,数百万印度...
//男子突然想起2个月前钓的鱼还在...
}
}
//1. 新闻类
class News{
private String total;
private String Text;
//2. 只初始化标题
public News(String total) {
this.total = total;
}
//1. 只打印标题
@Override
public String toString() {
return "News{" +
"total='" + total + '\'' +
'}';
}
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public String getText() {
return Text;
}
public void setText(String text) {
Text = text;
}
}
题目2:
注意: addAll removeAll 和containsAll 都是 需要传入一个Collection<Car> 类型的集合
package com.javastudy;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @Author: qianl
* @Date: 2022/12/17 13:04
* @Description:
*/
public class HomeWork02_ {
public static void main(String[] args) {
List<Car> listCar = new ArrayList<Car>();
Car car = new Car("宝马", 40000000);
Car car1 = new Car("宾利", 500000000);
//ArrayList 操作练习
listCar.add(car);
listCar.add(car1);
//删除
listCar.remove(car);
//查
System.out.println(listCar.contains(car));
//false
//长度
System.out.println(listCar.size());
//1
//是否空
System.out.println(listCar.isEmpty());
//false
//清空
listCar.clear();
List<Car> list = new ArrayList<Car>();
list.add(car);
list.add(car1);
//addAll 添加多个元素; 从index 处 开始加入
listCar.addAll(0,list);
//containsAll 查看
System.out.println(listCar.containsAll(list));
//true
list.removeAll(listCar);
System.out.println(list);
//[]
Iterator<Car> iterator = listCar.iterator();
while (iterator.hasNext()) {
Car next = iterator.next();
System.out.println(next);
}
for (Car car2 : listCar) {
System.out.println(car2);
}
/*Car{name='宝马', p=40000000}
Car{name='宾利', p=500000000}*/
}
}
class Car{
private String name;
private Integer p;
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", p=" + p +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getP() {
return p;
}
public void setP(Integer p) {
this.p = p;
}
public Car(String name, Integer p) {
this.name = name;
this.p = p;
}
}
题目3:
注意:
package com.javastudy;
import java.util.*;
/**
* @Author: qianl
* @Date: 2022/12/17 14:34
* @Description:
*/
public class HomeWork03_ {
@SuppressWarnings("all")
public static void main(String[] args) {
//使用HashMap 进行存储
Map empMap = new HashMap();
emp jack = new emp("jack", 650);
emp tom = new emp("tom", 1200);
emp smith = new emp("smith", 2900);
//添加
empMap.put(jack.getName(), jack.getPc());
empMap.put(tom.getName(), tom.getPc());
empMap.put(smith.getName(), smith.getPc());
//修改
empMap.put("jack",2600); //再次添加来修改
empMap.replace("jack",2600);//替代
//EntrySet方法:
Iterator iterator = empMap.entrySet().iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
Map.Entry me=(Map.Entry)next;
//1. 遍历员工
System.out.println(me.getKey());
}
while (iterator.hasNext()) {
Object next = iterator.next();
Map.Entry me=(Map.Entry)next;
//2. 遍历工资
System.out.println(me.getValue());
}
//keySet()方法
Set set = empMap.keySet();
for (Object o : set) {
System.out.println(o+":"+empMap.get(o));
}
//构造器:
Iterator iterator1 = empMap.keySet().iterator();
while (iterator1.hasNext()) {
Object next = iterator1.next();
System.out.println(next+"--"+empMap.get(next));
}
}
}
class emp{
private String name;
private int pc;
@Override
public String toString() {
return "emp{" +
"name='" + name + '\'' +
", pc=" + pc +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
emp emp = (emp) o;
return pc == emp.pc &&
Objects.equals(name, emp.name);
}
@Override
public int hashCode() {
return Objects.hash(name, pc);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPc() {
return pc;
}
public void setPc(int pc) {
this.pc = pc;
}
public emp(String name, int pc) {
this.name = name;
this.pc = pc;
}
}
题目4:
HashSet和TreeSet 实现去重:
HashSet:
-
获取相同的hash值 同时,比较内容 .则 e = p 当前元素 = 前一个元素 在for循环中
(p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
-
然后返回oldValue 不返回null;
V putVal(int hash, K key," V value", boolean onlyIfAbsent,
boolean evict) {
//1
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
//2
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
//3 重点 使得传入的值
e.value = value; //value 是当前传入的value值
afterNodeAccess(e);
return oldValue;
}
TreeSet:
- 第一次传入的时候 进行null检查
- 第二次传入值 看是否有Comparator 的传入
- 没有Comparator 的时候
//1. 第一次传入 会进行null检查 因为TreeSet(TreeMap) 不允许有null
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
//2. Comparator传入就走这个 走左右支 顺序是先左后右 遍历去重
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
//修改value值 就是去重
return t.setValue(value);
} while (t != null);
}
//3,没有Comparator 的时候 遍历去重 先左后右
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
//修改value值 就是去重
return t.setValue(value);
} while (t != null);
}
//开始放入元素 parent记录了位置
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);//插入后修复平衡二叉树
题目5:
TreeSet 内不能有null值 newPerson() 是有地址的 在堆里 value是默认的 new Object()
-
因为第一次添加: t == null;
-
走compare(key,key)进行判断
~~~java
Entry<K,V> t = root;
if (t == null) {
compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null); size = 1; modCount++; return null;
}
// comparatornull 对 走这个 ((Comparable<? super K>)k1).compareTo((K)k2) 走的super K的 因为Person() 没有重写相关方法
// Comparable 的compareTo() 没有重写 就会把 new Person() 强转成 Comparable类:
// 报错 ClassCastException 强制类型转换异常.
final int compare(Object k1, Object k2) {
return comparatornull ? ((Comparable<? super K>)k1).compareTo((K)k2)
: comparator.compare((K)k1, (K)k2);
}
//所以 如果
class Person implements Comparable{
//重写 compareTo()方法 什么都不写 就不会报错了
//能输出出来是一个对象地址
}
~~~
题目6:
// 注意p1 是按现在的key值是person() 对象 所以他会去找p1(“cc”,1001) 但是hashSet里没有这个东西
p1是add后 计算hashCode 然后再改成CC hashCode没变 而p1是变以后的hashCode 就变了
主要是 HashCode ”AA“ 与"CC" 的值不一样 返回的hash值也就不一样
题目7:
PS: add() append() put() // remove() delete()的区别
add()
append()
put()
返回类型 和 删除的东西不一样
泛型:通用性
初始记忆: 使得泛型中的导入类型 是什么都可以
导入:
// 报错ClassCastException
public static void main(String[] args) {
Dog dog1 = new Dog("001", 1);
List list = new ArrayList();
list.add(dog1);
//如果混入了一只猫
list.add("Car");
for (Object o : list) {
//向下转型 .ClassCastException
Dog dog = (Dog)o;
System.out.println(dog);
}
}
原因:
- 不能对加入的数据类型进行规范 约束 (不安全)
- 遍历时,需要使用类型转换,如果集合中的数据量较大,对效率有影响(多次向下转型)
使用泛型来解决:
public static void main(String[] args) {
Dog dog1 = new Dog("001", 1);
// 1. <Dog> 表示ArrayList中的元素是Dog
List<Dog> list = new ArrayList<Dog>();
list.add(dog1);
//2. 如果混入了一只猫 直接编译不通过
//list.add("Car");
//3.Dog o:list 可以直接写Dog类型 不用转换.
for (Dog o : list) {
//不向下转型
System.out.println(o);
}
}
- Jdk5.0以后出现
- 不会在运行时出现ClassCastException
- 可以是某个类 \ 方法 \ 参数类型
测试:
package com.generic;
/**
* @Author: qianl
* @Date: 2022/12/17 21:27
* @Description:
*/
public class Generic01 {
public static void main(String[] args) {
//E 的具体类型 在创建时(编译时) 就确定了
Person<String> stringPerson = new Person<String>("Test");
System.out.println(stringPerson.getS()); // Test
}
}
class Person<E>{
E s;// E 表示s的数据类型 有点像占位符 E通常表示Element;
public Person(E s) {
this.s = s;
}
public void setS(E s) {
this.s = s;
}
public E getS(){
return s;
}
}
书写格式:
泛型有T E V K K: Key V: Value E: element T 表示Type 四个都可以 都表示类型
泛型的声明:
List 和 ArrayList 那样
K T V 不表示值 ,而表示类型
任何字母都行 通常大写
可以是类 属性 形参列表 返回属性等.
class Person<E> {
E s;// E 表示s的数据类型 有点像占位符 E通常表示Element;
public Person(E s) {
this.s = s;
}
public void setS(E s) {
this.s = s;
}
public E getS() {
return s;
}
}
泛型的实例化:举例 HashSet 和HashMap的使用情况:
package com.generic;
import java.util.*;
/**
* @Author: qianl
* @Date: 2022/12/19 17:43
* @Description:
*/
public class Generic02 {
public static void main(String[] args) {
//Test HashSet;
HashSet<Student> students = new HashSet<>();
students.add(new Student("john",12));
//标注了迭代器的类型
Iterator<Student> iterator = students.iterator();
//不需要转换
while (iterator.hasNext()) {
Student next = iterator.next();
System.out.println(next);
}
//Student{name='john', age=12}
HashMap<Integer, Student> studentIntegerHashMap = new HashMap<>();
studentIntegerHashMap.put(10001,(new Student("King",35)));
studentIntegerHashMap.put(10002,(new Student("King",36)));
//使用EntrySet()遍历
Iterator<Map.Entry<Integer, Student>> iterator1 = studentIntegerHashMap.entrySet().iterator();
while (iterator1.hasNext()) {
//可以不用手动向下转型了
Map.Entry<Integer, Student> next = iterator1.next();
System.out.println("学生ID:"+next.getKey()+ " 学生信息:"+next.getValue());
}
//学生ID:10001 学生信息:Student{name='King', age=35}
//学生ID:10002 学生信息:Student{name='King', age=36}
}
}
class Student{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
泛型使用细节:
注意:
-
java中 标注了T 和E的 都只能是引用类型
-
在指定泛型具体类型后,可以传入该类型或者其子类类型
-
fanx1使用可以只写前面一个<> 后一个会提示: Explicit type argument Student can be replaced with <>
(显式类型参数Student可以替换为<>) 他会自行进行类型推断
-
如果没写<> 是默认类型 <E> E则是Object类型
泛型课堂练习:
题目1:
重点
- 编写MyDate类的比较方法
- 使用匿名内部类定制排序
- 日期的判断 (一步一步来 过关斩将)
- 自己写方法 可以参考String的compareTo方法 只写一个形参 注意要静态
- 可以将方法转为lambda表达式
- 注意老韩写法 直接在方法里进行判断 没有创建 compareTo方法 最后也封装在MyDate里
public static int compareTo(Object o1, Object o2) {
//先进行Object的转型
if (o1 instanceof MyDate || o2 instanceof MyDate) return 0;
//开始向下转型
MyDate d1 = (MyDate) o1;
MyDate d2 = (MyDate) o2;
//写一个另外的方法开始比较year day month
return ct(d1, d2);
}
public static int ct(MyDate o1, MyDate o2) {
//先排除完全对等的情况:
if (o1.year == o2.year && o1.month == o2.month && o1.day == o2.day) return 0;
//如果年月都相等 比较日期
if (o1.year == o2.year && o1.month == o2.month) {
return o1.day - o2.day;
}
//如果年相等 比较月份
if (o1.year == o2.year) {
return o1.month - o2.month;
}
//否则直接返回年的值
return o1.year - o2.year;
}
注意老韩写法: 最后也封装在MyDate里
employees.sort((o1,o2)->{
if (!(o1 instanceof Employee && o2 instanceof Employee)) return 0;
//比较年龄
if (o1.getName().equals(o2.getName())) return o1.getName().compareTo(o2.getName());
//比较年
int year=o1.getBirthday().getYear()-o2.getBirthday().getYear();
if (year!=0) return year;
//比较月
int month = o1.getBirthday().getMonth()-o2.getBirthday().getMonth();
if (month!=0) return month;
//比较日
return o1.getBirthday().getDay()-o2.getBirthday().getDay();
});
package com.generic;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Map;
import java.util.Objects;
/**
* @Author: qianl
* @Date: 2022/12/19 18:35
* @Description:
*/
public class Generic03 {
public static void main(String[] args) {
Employee john = new Employee("john", "30000", new MyDate(2000, 12, 10));
Employee tom = new Employee("tom", "30000", new MyDate(2000, 12, 10));
Employee jir = new Employee("jir", "30000", new MyDate(2000, 12, 10));
ArrayList<Employee> employees = new ArrayList<>();
employees.add(john);
employees.add(tom);
employees.add(jir);
//可以转为lambda表达式
employees.sort(new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
//判断类型
if (!(o1 instanceof Employee && o2 instanceof Employee)) return 0;
//名字排序
if (o1.getName().equals(o2.getName())) {
//String的自然排序
return o1.getName().compareTo(o2.getName());
} else {
// 注意将compareTo方法改为静态
return MyDate.compareTo(o1.getBirthday(), o2.getBirthday());
}
}
});
for (Employee employee : employees) {
MyDate birthday = employee.getBirthday();
System.out.println(employee.getName() + "," + employee.getSal() + ","
+ birthday.getYear() + "年" + birthday.getMonth() + "月" + birthday.getDay() + "日");
}
}
}
class MyDate {
private int year;
private int month;
private int day;
public static int compareTo(Object o1, Object o2) {
//先进行Object的转型
if (o1 instanceof MyDate || o2 instanceof MyDate) return 0;
//开始向下转型
MyDate d1 = (MyDate) o1;
MyDate d2 = (MyDate) o2;
//写一个另外的方法开始比较year day month
return ct(d1, d2);
}
public static int ct(MyDate o1, MyDate o2) {
//先排除完全对等的情况:
if (o1.year == o2.year && o1.month == o2.month && o1.day == o2.day) return 0;
//如果年月都相等 比较日期
if (o1.year == o2.year && o1.month == o2.month) {
return o1.day - o2.day;
}
//如果年相等 比较月份
if (o1.year == o2.year) {
return o1.month - o2.month;
}
//否则直接返回年的值
return o1.year - o2.year;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyDate myDate = (MyDate) o;
return year == myDate.year &&
month == myDate.month &&
day == myDate.day;
}
@Override
public int hashCode() {
return Objects.hash(year, month, day);
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
class Employee {
private String name;
private String sal;
private MyDate birthday;
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", sal='" + sal + '\'' +
", birthday=" + birthday +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return Objects.equals(name, employee.name) &&
Objects.equals(sal, employee.sal) &&
Objects.equals(birthday, employee.birthday);
}
@Override
public int hashCode() {
return Objects.hash(name, sal, birthday);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSal() {
return sal;
}
public void setSal(String sal) {
this.sal = sal;
}
public MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
public Employee(String name, String sal, MyDate birthday) {
this.name = name;
this.sal = sal;
this.birthday = birthday;
}
}
lambda表达式:
当该接口中有且只有一个方法时, 可以使用lambda表达式 将方法参数直接写出来 不用写明重写的方法是哪个.
//可以转为lambda表达式
employees.sort(new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
//名字排序
if (o1.getName().equals(o2.getName())) {
//String的自然排序
return o1.getName().compareTo(o2.getName());
} else {
// 注意将compareTo方法改为静态
return MyDate.compareTo(o1.getBirthday(), o2.getBirthday());
}
}
});
//转为lambda表达式 o1 o2就是sort方法中只有一个需要重写的方法的传入参数
employees.sort((o1, o2) -> {
//名字排序
if (o1.getName().equals(o2.getName())) {
//String的自然排序
return o1.getName().compareTo(o2.getName());
} else {
// 注意将compareTo方法改为静态
return MyDate.compareTo(o1.getBirthday(), o2.getBirthday());
}
});
自定义泛型:
- 成员可以使用泛型
- 泛型数组 不能初始化
- 静态因为初始就加载在类加载器里 所以不能使用类的泛型
- 泛型类 在创建时确定类型的 填入<>中
- 没有指定时 就是Object;
package com.generic;
/**
* @Author: qianl
* @Date: 2022/12/19 21:05
* @Description:
*/
public class CustomGeneric {
public static void main(String[] args) {
Tiger<Double,String,Integer> g = new Tiger<>("john");
g.setT(10.9);//相当于给T 进行了 Double t = 10.9;
//g.setT("yy");//运行失败 已经标记过了是Double类型
System.out.println(g);
//Tiger{name='john', r=null, m=null, t=10.9}
Tiger g2 =new Tiger("john~~~");
g2.setT("yy");
System.out.println(g2);
//Tiger{name='john~~~', r=null, m=null, t=yy}
}
}
class Tiger<T,R,M>{
String name;
R r;
M m; //属性使用泛型
T t;
//因为 数组在new 不能确定T 的类型 就无法在内存中开空间
//T[] ts =new T[9];
//无法直接实例化类型参数“T”
//Type parameter 'T' cannot be instantiated directly
@Override
public String toString() {
return "Tiger{" +
"name='" + name + '\'' +
", r=" + r +
", m=" + m +
", t=" + t +
'}';
}
public Tiger(String name, R r, M m, T t) {//构造器使用泛型
this.name = name;
this.r = r;
this.m = m;
this.t = t;
}
public Tiger(String name) {
this.name = name;
}
//因为静态是类加载时(对象未创建时) 就存在了 所以不能确定类型 除非指定类型
/*public static void m1(M m){
}*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public R getR() {//方法使用泛型
return r;
}
public void setR(R r) {
this.r = r;
}
public M getM() {
return m;
}
public void setM(M m) {
this.m = m;
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
自定义泛型(接口):
-
接口中 一样 静态不能使用
-
接口类型 在继承接口或者 实现接口的时候确定
-
没有指定类型, 就Object
interface A<U,R>{
R r;
//U u = "java"; 报错
void hi(R r);
void run(R r);
//可以写默认方法 default类型 然后不需要重写
default R method(U u){
return null;
}
}
//实现接口 或者继承接口时 定义类型 没有指定就是Object
class a implements A<String,Double>{
@Override
public void hi(Double aDouble) {
}
@Override
public void run(Double aDouble) {
}
}
自定义泛型方法:
泛型方法 普通类 泛型类中都可以 也就是
可以在任意类中写一个泛型的方法
被调用时 类型被确认
public void eat(E e){} 修饰符后没有<E,R,...> 这种不算泛型方法 只是使用泛型
案例:
//<A> 是泛型 给Ea使用的
public <A> void Ea(A t){
}
泛型方法练习:
泛型类{
问题 public void eat(U u){} 使用泛型 U没有声明
泛型方法(E e){
传入的10 会自动装箱 --> Integer 输出Integer
传入new Dog() //类型 Dog 输出的Dog
}
}
泛型的继承和通配符:
-
泛型不具备继承性!
List<Object> list = new ArrayList<String>(); 不行! 要么一致 要么后面不写
-
<?> 表示支持所有泛型类型
- : **支持A及其所有子类**, **规定了泛型的上限**
- **支持A类以及A类的父类**, 不限于直接父类 ,**规定了泛型的下限**
-
package com.generic; import sun.java2d.pipe.SpanIterator; import java.util.List; /** * @Author: qianl * @Date: 2022/12/20 10:44 * @Description: */ public class GenericExtends { public static void main(String[] args) { } //支持任意 也就是Object了 public static void pc1(List<?>c){ for (Object o : c) { System.out.println(o);//Object类型 } } //规定上限 父类以下的全部 public static void pc2(List<? extends AA>c){ for (AA aa : c) { System.out.println(aa); } } //规定下限 那上限到Object 不限于直接父类:父类的父类也行 public static void pc3(List<? super CC>c){ for (Object o : c) { System.out.println(o); } } } class AA{} class BB extends AA{} class CC extends BB{}
本章作业:
题目1:
泛型类 使用泛型的方法
泛型方法 还有Junit单元测试类 可以不使用main方法
-
new JUnit_.m1(); 这样使用
-
第二种 直接@Test 就可以了 可以将本来要放在主方法的测试 放在另一个方法中 然后运行该方法 .
-
需要添加 JUnit5.4
package com.generic;
import com.sun.xml.internal.bind.v2.model.core.ID;
import java.util.*;
/**
* @Author: qianl
* @Date: 2022/12/20 11:04
* @Description:
*/
public class HomeWork01 {
public static void main(String[] args) {
//创建User 并放进DAO中 使用其中的五个方法.
User john = new User(1001, 30, "john");
User tom = new User(1002, 33, "tom");
User jack = new User(1003, 30, "jack");
DAO<User> userDAO = new DAO<>();
//1. save 添加元素
userDAO.save("10001",john);
userDAO.save("10002",tom);
userDAO.save("10003",jack);
//2. 获取返回对象
User user = userDAO.get("10002");
System.out.println(user);
//User{id=1002, age=33, name='tom'}
//3. 替换值
userDAO.update("10003",new User(1003, 30, "yeas"));
System.out.println(userDAO.get("10003"));
//User{id=1003, age=30, name='yeas'}
//4. 返回全部T类型
Iterator<User> iterator = userDAO.list().iterator();
while (iterator.hasNext()) {
User next = iterator.next();
System.out.println(next);
}
/*User{id=1002, age=33, name='tom'}
User{id=1001, age=30, name='john'}
User{id=1003, age=30, name='yeas'}*/
//5. 删除指定id对象
userDAO.delete("10003");
}
}
class DAO<T>{
//需要给上元素
Map<String,T> tMap = new HashMap<>();
//1 保存T类型的对象 到 tMap里
public void save(String id,T entity){
tMap.put(id,entity);
}
//2 从tMap中获取id 对应的对象
public T get(String id){
//get 可能会判断Map中的value值
return tMap.get(id);
}
//3 替换key为id 的内容 改为entity对象
public void update(String id,T entity){
//重复添加 就能替换entity;
tMap.put(id,entity);
}
//4 返回map中存放的所有T对象
public List<T> list(){
List<T> list = new ArrayList<>(); //初始化第一次添加后有16容量
//直接增强for 遍历对象是 tMap.entrySet()
for (Map.Entry<String, T> next : tMap.entrySet()) {
//依次添加 可能空指针 所以需要给list进行初始化容量
list.add(next.getValue());
//方法调用“add”可能会产生“NullPointerException”
}
return list;
}
//5 删除指定id对象
public void delete(String id){
tMap.remove(id);
}
}
class User{
private int id;
private int age;
private String name;
@Override
public String toString() {
return "User{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id == user.id &&
age == user.age &&
Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(id, age, name);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
}
单词
英语 | 意思 |
---|---|
getInstance | 获取实例 |
Abstract | 抽象类 |
interface | 接口 |
implement | 执行 实施 使生效 |
default | 默认 |
instantiated | 实例化 |
inner | 内部 |
Anonymous | 匿名的 不公开的 |
protected | 保护 |
private | 私有的 |
ordinal | |
enumeration | |
season | |
autumn | |
winter | |
instanceof | |
compareTo | |
Documented | |
field | |
constructor | |
package | |
parameter | |
Documented | |
Inherited | |
exception | |
Throws | |
clone | |
Found | |
Support | |
Serializable | 可串行的 |
wrapper | 包装 |
append | 追加 |
synchronized | 已同步 |
scan | 扫描 |
Instance | 实例 |
plus | 加 |
minus | 减 |
Character | |
Integer | |
Uppercase | |
lowercase | |
system | 系统 |
math | |
substring | 子字符串 |
digit | 数字 |
format | 格式化 |
Exception | |
reverse | |
Comparator | |
compare | |
collection | 收集 聚集 <接口> |
map | 图 地图 |
collections | 收集 聚集 包装类 |
chapter | |
vector | 矢量 载体 |
linked | 链接的 |
iterable | 可迭代的 可重复的 |
Empty | 空的 |
contains | |
iterator | 迭代器 |
stream | 流动 |
put | 放 放置 |
add | 增加 |
append | 追加 |
remove | 去除 |
delete | 删除 |
contains | 包含 |
element | 元素 要素 |
instant | 瞬间 (时间戳) |
Exercise | |
synchronized | 同步的 |
RandomAccess | 随机存储 |
Clone | 克隆 |
empty | 空的 |
count | 数 |
next | 下一个 |
prev | 前一个 |
exercise | 练习 |
employee | 员工 |
增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete)
instance 获取实例
abstract 抽象类
interface 接口
implement 执行 实施 使生效
default 默认
instantiated 实例化
inner 内部
anonymous 匿名的 不公开的
protected 保护
private 私有的
encapsulation 封装
account 账户
password 密码
balance 平衡;余额
extends 继承
pupil 小学生
graduate 大学毕业生
access 接近 权力
theory 理论 学说 原理
structure 结构
dynamic 动态
binding 绑定 结合
equal 平等的
monster 怪物
master 主人
resume 简历
details 细节
------------恢复内容结束------------