一、引入
二、Collection接口
package com.atguiguday01.a_collection;
import java.util.ArrayList;
import java.util.Collection;
public class Demo01Collection {
public static void main(String[] args) {
/**
* 格式
* Collection<E> 集合名 = new 实现类对象<E>()
* **/
Collection<String> collection1 = new ArrayList<>();
//boolean add(E e) : 将给定的元素添加到当前集合中(我们一般调add时,不用boolean接收,因为add一定会成功)
collection1.add("刘备");//只要写字符串就会直接添加进去
collection1.add("刘备");//不用布尔类型去接收,一定能接收,编译时就直接报错了
collection1.add("关羽");
collection1.add("张飞");
collection1.add("诸葛亮");
collection1.add("庞统");
System.out.println(collection1);
System.out.println("=========================");
/**
* boolean addAll(Collection<? extends E> c) :将另一个集合元素添加到当前集合中 (集合合并)
* **/
Collection<String> collection2 = new ArrayList<>();
collection2.add("宋江");
collection2.add("林冲");
collection2.add("卢俊义");
collection1.addAll(collection2);
System.out.println(collection1);
System.out.println("=========================");
//void clear():清除集合中所有的元素
//collection1.clear();
//System.out.println(collection1);
System.out.println("=========================");
//boolean contains(Object o) :判断当前集合中是否包含指定的元素
boolean result01 = collection1.contains("刘备");
System.out.println(result01);
System.out.println("=========================");
//boolean isEmpty() : 判断当前集合中是否有元素->判断集合是否为空(指的是元素)
boolean result02 = collection1.isEmpty();
System.out.println(result02);
System.out.println("=========================");
//boolean remove(Object o):将指定的元素从集合中删除
collection1.remove("刘备");
System.out.println(collection1);
System.out.println("=========================");
//int size() :返回集合中的元素个数。
System.out.println(collection1.size());
System.out.println("=========================");
//Object[] toArray(): 把集合中的元素,存储到数组中
Object[] arr = collection1.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
三、迭代器
1)迭代器的基本使用
public class Demo01Iterator {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("贾宝玉");
list.add("林黛玉");
list.add("王熙凤");
list.add("刘姥姥");
list.add("探春");
//获取Iterator接口
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){//如果 有的话获取下一个
String element = iterator.next();
System.out.println("element = " + element);
}
}
}
注意:在进行迭代的时候,不能连续多次调用next方法,一次2个,第三次不够
public class Demo02Iterator {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("唐三藏");
list.add("孙悟空");
list.add("猪悟能");
list.add("沙悟净");
list.add("白龙马");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
System.out.println(iterator.next());
}
}
}
2)迭代器的迭代过程
3)迭代器的底层原理使用说明
public class Demo03Iterator {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("张三");
set.add("李四");
Iterator<String> iterator = set.iterator();
}
}
4)并发修改异常
/**出现并发异常的代码**/
public class Demo04Iterator {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("唐僧");
list.add("孙悟空");
list.add("猪八戒");
list.add("沙和尚");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
String element = iterator.next();
if ("猪八戒".equals(element)){
list.add("白龙马");
}
}
System.out.println(list);
}
}
Iterator<String> iterator = list.iterator();
String element = iterator.next();
=================================================
private class Itr implements Iterator<E> {
/*
expectedModCount:预期操作次数
modCount:实际操作次数
*/
int expectedModCount = modCount;
public E next() {
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)//如果实际操作次数和预期操作次数不相等,抛异常
throw new ConcurrentModificationException();
}
public class Demo05Iterator {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("唐僧");
list.add("孙悟空");
list.add("猪八戒");
list.add("沙和尚");
ListIterator<String> iterator = list.listIterator();
while(iterator.hasNext()){
String element = iterator.next();
if ("猪八戒".equals(element)){
iterator.add("白龙马");
}
}
System.out.println(list);
}
}
5)数据结构知识补充
1-为什么需要数据结构
数据的逻辑
2-常见的几种数据结构的介绍
四、List接口
1)List集合下的实现类
2)ArrayList集合使用
/**arraylist基本操作1**/
public class Demo01ArrayList {
public static void main(String[] args) {
/**
格式:ArrayList<泛型> 集合名 = new ArrayList<>()
* **/
ArrayList<String> list = new ArrayList<>();
/**boolean add(E e) ->将元素添加到集合中->尾部(add方法一定能添加成功的,所以我们不用boolean接收返回值)**/
System.out.println("初始化后的集合:");
list.add("张三");//向集合中的末尾添加元素
list.add("李四");
list.add("王五");
list.add("赵六");
list.add("田七");
System.out.println(list);//输出初始化后的集合
System.out.println("============================================");
System.out.println("在指定位置上添加元素后输出");
//void add(int index, E element) ->在指定索引位置上添加元素
list.add(0,"猪八");
System.out.println("list = " + list);
//boolean remove(Object o) ->删除指定的元素,删除成功为true,失败为false
//boolean result01 = list.remove("猪八");
//System.out.println("result01 = " + result01);看输出的值是否成功删除
//System.out.println("list = " + list);
//E remove(int index) -> 删除指定索引位置上的元素,返回的是被删除的那个元素
System.out.println("============================================");
System.out.println("删除List上第一个元素");
String element1 = list.remove(0);
System.out.println("element1 = " + element1);
System.out.println("list = " + list);
//E set(int index, E element) -> 将指定索引位置上的元素,修改成后面的element元素
System.out.println("============================================");
String element2 = list.set(0, "曼曼");//返回set修改的元素:“曼曼”
System.out.println("element2 = " + element2);
System.out.println("list = " + list);
//E get(int index) -> 根据索引获取元素
System.out.println(list.get(0));
//int size() -> 获取集合元素个数
System.out.println(list.size());
}
}
package com.atguiguday01.c_list;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 迭代器遍历ArrayList
*
* **/
public class Demo02ArrayList {
public static void main(String[] args) {
//创建集合
ArrayList<String> list = new ArrayList<>();
//boolean add(E e) -> 将元素添加到集合中->尾部(add方法一定能添加成功的,所以我们不用boolean接收返回值)
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
list.add("田七");
//迭代器创建
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("===================");
for (int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
/**
在集合有索引的情况下,普通for循环遍历快捷键:集合名.fori
**/
System.out.println("==================");
for (int i = 0; i < list.size(); i++) {//根据索引获取元素
System.out.println(list.get(i));
}
}
}
import java.util.ArrayList;
/**
*List接口_删除时要注意的问题说明
* **/
public class Demo03ArrayList {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(2);//元素2存到了0索引上
/*
remove(2) -> 调用的是remove(int index) -> 按照索引删除元素
但是是存在第0个位置上的
解决:
将2转成包装类
*/
//list.remove(2);
list.remove(new Integer(2));
System.out.println(list);
}
}
【ArrayList底层源码分析】
ArrayList<Integer> list = new ArrayList<>();
=============================================
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//已经创建声明了
transient Object[] elementData;-> ArrayList底层的那个数组
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
在源码中,具体过程演示
无参构造源码分析
**/
list.add("abc");
=============================================
public boolean add(E e) { -> abc
ensureCapacityInternal(size + 1); // Increments modCount!!
}
//size还是个成员变量,记录元素个数,如果有元素就加1
private void ensureCapacityInternal(int minCapacity -> 1) {//计算容量
ensureExplicitCapacity(calculateCapacity(elementData->空数组, minCapacity->1));//接收下面返回的方法10
}
// 先传参数,数组一开始时空的,然后传进下面的方法
// ensureExplicitCapacity(calculateCapacity(10));
private static int calculateCapacity(Object[] elementData->空数组, int minCapacity->1) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//相等
return Math.max(DEFAULT_CAPACITY, minCapacity->1); -> 返回的是10
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity->10) {
modCount++;//实际操作次数加1
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity->10);
}
private void grow(int minCapacity->10) {
// overflow-conscious code
int oldCapacity = elementData.length;//获取数组的老的容量 0
int newCapacity = oldCapacity + (oldCapacity >> 1);//计算数组新的容量 -> 0
if (newCapacity - minCapacity < 0)//比较新旧数组容量
newCapacity = minCapacity;//newCapacity = 10
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
//elementData = Arrays.copyOf(老数组,10) 老数组扩容为10 然后会产生一个新数组,赋给 elementData
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
下面是有参构造源码分析
**/
ArrayList<String> list2 = new ArrayList<>(10);
=============================================
public ArrayList(int initialCapacity->10) {
if (initialCapacity > 0) {//小于0 就直接甩异常了
this.elementData = new Object[initialCapacity];//直接创建数组,长度为指定容量
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
五、List 的接口 LinkedList
1)LinkedList常用类实现
package com.atguiguday01.c_list;
/**常用方法介绍,代码演示**/
import java.util.Iterator;
import java.util.LinkedList;
public class Demo05LinkedList {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("虹猫蓝兔七侠传");//直接添加元素到第0个位置
list.add("海绵宝宝");
list.add("天线宝宝");
list.add("花园宝宝");
list.add("托马斯小火车");
list.add("数码宝贝");
list.add("神奇宝贝");
list.add("游戏王");
list.add("灌篮高手");
list.add("火影忍者");
System.out.println("输出添加完元素后的集合");
System.out.println(list);
//- public void addFirst(E e):将指定元素插入此列表的开头。
System.out.println("=====================================================================================");
System.out.println("\n"+"输出将指定元素:网球王子 插入此列表的开头");
list.addFirst("网球王子");
System.out.println(list);
//- public void addLast(E e):将指定元素添加到此列表的结尾。
System.out.println("=====================================================================================");
System.out.println("\n"+"输出将指定元素 七龙珠 插入此列表的末尾");
list.addLast("七龙珠");
System.out.println(list);
//- public E getFirst():返回此列表的第一个元素。
System.out.println("=====================================================================================");
System.out.println("\n"+"输出这个列表的第一个元素");
System.out.println(list.getFirst());
//- public E getLast():返回此列表的最后一个元素。
System.out.println("=====================================================================================");
System.out.println("\n"+"输出这个列表的最后一个元素");
System.out.println(list.getLast());
//- public E removeFirst():移除并返回此列表的第一个元素。
System.out.println("=====================================================================================");
System.out.println("\n"+"删掉列表第一个元素,并返回删除的元素");
System.out.println(list.removeFirst());
System.out.println(list);
//- public E removeLast():移除并返回此列表的最后一个元素。
System.out.println("=====================================================================================");
System.out.println("\n"+"删掉列表最后一个元素 七龙珠 ,并返回删除的元素");
System.out.println(list.removeLast());
System.out.println(list);
//- public boolean isEmpty():如果列表不包含元素,则返回true。
System.out.println("=====================================================================================");
System.out.println("\n"+"如果列表不包含元素,就返回真值true");
System.out.println(list.isEmpty());
System.out.println("===================================");
//用迭代器去遍历
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//用for循环去遍历
System.out.println("===================================");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
【了解】
public class Demo06LinkedList {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("虹猫蓝兔七侠传");
list.add("海绵宝宝");
list.add("天线宝宝");
list.add("花园宝宝");
//public E pop():从此列表所表示的堆栈处弹出一个元素。----》弹出第一个元素
list.pop();
System.out.println(list);
//public void push(E e):将元素推入此列表所表示的堆栈。
list.push("曼曼");
System.out.println(list);
}
}
2)LinkedLIst底层原理分析
(1)LinkedList底层成员解释说明
1.LinkedList底层成员
transient int size = 0; 元素个数
transient Node<E> first; 第一个节点对象
transient Node<E> last; 最后一个节点对象
2.Node代表的是结点对象
private static class Node<E> {
E item;//节点上的元素
Node<E> next;//记录着下一个节点地址
Node<E> prev;//记录着上一个节点地址
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
(2)LinkedList底层add方法源码分析
LinkedList<String> list = new LinkedList<>();
list.add("a");
list.add("b");
void linkLast(E e) {
// 将当前的last节点赋值给临时变量l
final Node<E> l = last;
// 创建一个新节点,其前驱节点为l,元素值为e,后继节点为null
final Node<E> newNode = new Node<>(l, e, null);
// 将最后一个节点指针指向新节点
last = newNode;
// 如果l为null,说明链表为空,将first指针也指向新节点
if (l == null)
first = newNode;
// 如果l不为null,将l的后继节点指向新节点
else
l.next = newNode;
// 链表大小增加1
size++;
// 修改次数增加1
modCount++;
}
/** 双向链的存储 ,,,二分法查找 比单向链方便的一个体现 **/
(3)LinkedList底层get方法源码分析
public E get(int index) {
// 检查Index是否合法
checkElementIndex(index);
// 返回指定位置节点的元素
return node(index).item;
}
// 根据索引获取节点
Node<E> node(int index) {
// 如果索引超过了元素数量,抛出IndexOutOfBoundsException
// assert isElementIndex(index);
if (index < (size >> 1)) {//用二分法查询
Node<E> x = first;
// 从头部向后遍历直到找到指定索引的节点
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
// 从尾部向前遍历直到找到指定索引的节点
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
六、增强for的使用
1)基本使用
/** 代码演示 **/
public class Demo01For {
public static void main(String[] args) {
// 创建一个ArrayList并添加元素
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张翠山");
list.add("张大彪");
list.add("李云龙");
list.add("楚云飞");
list.add("魏大勇");
list.add("秀琴大妹子");
list.add("二营长");
// 使用增强for循环遍历ArrayList并打印每个元素
for (String s : list) {
System.out.println(s);
}
System.out.println("==============");
// 创建一个数组并赋初值
int[] arr = {1,2,3,4,5};
// 使用增强for循环遍历数组并打印每个元素
for (int i : arr) {
System.out.println(i);
}
}
}
2)注意点
七、Collection集合工具类
public class Demo01Collections {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
// static <T> boolean addAll(Collection<? super T> c, T... elements)->批量添加元素
Collections.addAll(list,"张三","李四","王五","赵六","田七","猪八");//向集合中添加若干元素
System.out.println(list);//输出添加列表
List<String> list1 = Arrays.asList("张三", "李四", "王五");
System.out.println("list1 = " + list1);
System.out.println("===========================================");
// static void shuffle(List<?> list) ->将集合中的元素顺序打乱
Collections.shuffle(list);
System.out.println(list);
System.out.println("===========================================");
ArrayList<String> list2 = new ArrayList<>();//创建一个 String类型的集合,并逐个添加元素
list2.add("by");
list2.add("c");
list2.add("d");
list2.add("a");
list2.add("bi");
// static <T> void sort(List<T> list) ->将集合中的元素按照默认规则排序 -> ASCII
Collections.sort(list2);//按照默认规则排序
System.out.println(list2);//输出
}
}
static <T> void sort(List<T> list, Comparator<? super T> c)->将集合中的元素按照指定规则排序
Comparator:接口,可以用作比较
方法:int compare(T o1, T o2)->实现比较的方法
o1-o2:升序
o2-o1:降序
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.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 String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Demo02Collections {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("柳岩",36));
list.add(new Person("涛哥",16));
list.add(new Person("曼曼",46));
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});
System.out.println(list);
}
}
public class Person implements Comparable<Person>{
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Person o) {
return this.getAge()-o.getAge();
}
}
public class Demo02Collections {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("柳岩",36));
list.add(new Person("涛哥",16));
list.add(new Person("曼曼",46));
/*Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});*/
Collections.sort(list);//元素里面已经实现了排序规则,所以排序的时候直接传集合
System.out.println(list);
}
}
八、泛型
1)为什么要使用泛型?
public class Demo1FanXing {
public static void main(String[] args) {
//定义一个集合,存储整型,字符串,布尔等类型数据,获取元素中字符串的长度
ArrayList<Object> list = new ArrayList<>();
list.add(1);
list.add("abc");
list.add("def");
list.add(2.5);
list.add(true);
for (Object o : list) {
String s = (String) o;//ClassCastException
System.out.println(s.length());//父类类型调用不了子类方法,所以强制转换,向下转型
}//然后会报错,会出现编译时异常
}
}
//object 类型去定义集合中的元素类型,极容易出现ClassCastException异常,类型转换异常 这就是不使用泛型的原因
2)泛型的定义
(1)含有泛型的类
public class MyArrayList<E>{//E此时就跟个占位符一样,无所谓的 代表
public void add(E e){//e变量名 E会和类上的E类型一致 返回值类型也可以写成e
System.out.println(e);
}
}
public class Test01 {
public static void main(String[] args) {
MyArrayList<String> list = new MyArrayList<>();//传一个字符串
list.add("abc");//统一引用类型为字符串
System.out.println("==========================");
MyArrayList<Integer> list2 = new MyArrayList<>();
list2.add(1);//统一引用类型为整型
}
}
(2)含有泛型的方法
public class Person {//含有泛型的一个方法
public <E> void eat(E e){
System.out.println(e);
}
}
public class Test01 {
public static void main(String[] args) {
Person person = new Person();
//调用的时候确定泛型中的引用类型是什么 String还是Integer
//想传什么类型就传什么类型。在调用的时候确定就行了
person.eat("哈哈哈");
person.eat(1);
}
}
(3)含有泛型的接口
public interface MyList<E>{//定义一个泛型接口 MyList
public abstract void add(E e);//定义一个抽象方法 参数类型和泛型保持一致 或者E也可以替换成其他引用数据类型
}
public class MyArrayList<E> implements MyList<E>{
@Override
public void add(E e) {//实现add类的时候
System.out.println(e);
}
}
public class Test01 {
public static void main(String[] args) {
MyArrayList<String> list = new MyArrayList<>();
list.add("我是MyArrayList的add方法");//第一种:new实现类对象的时候确定类型
}
}
public interface MyIterator<E> {//实现一个接口
E next();
}
public class MyScanner implements MyIterator<String>{
@Override//直接重写
public String next() {//实现类的时候直接确定泛型类型为String
return "重写的next方法";//返回值变成字符串
}
}
public class Test02 {
public static void main(String[] args) {
MyScanner myScanner = new MyScanner();
String data = myScanner.next();
System.out.println("data = " + data);//返回一个字符串类型的泛型,给实现类,并输出
}
}
3)泛型的高级应用
(1)泛型通配符
public class Test01 {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();//new一个ArrayList集合并逐步添加元素
list1.add("张三");
list1.add("李四");
list1.add("王五");
list1.add("赵六");
ArrayList<Integer> list2 = new ArrayList<>();//迭代器
list2.add(1);
list2.add(2);
method(list1);
method(list2);
}
// 使用泛型通配符,可以接受任何类型,诸如上述的String和Integer,也可以省略不写
public static void method(ArrayList<?> list){
for (Object o : list) {
System.out.println(o);/输出调用集合中的元素
}
}
}
?的引出问题
(2)泛型的上限下限
/**
*子父类关系
* Integer -> Number -> Object
*
* String -> Object
*/
public class Test02 {
public static void main(String[] args) {
//四个集合
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<Number> list3 = new ArrayList<>();
ArrayList<Object> list4 = new ArrayList<>();
get1(list1);
//get1(list2); //报错,String和Number没有关系
get1(list3);
//get1(list4);//报错,Object类型是Number的父类,传下限
System.out.println("=================");
//get2(list1);//报错,Integer是Number的子类,传上限
//get2(list2);//报错,String和Number没有关系
get2(list3);
get2(list4);
}
//上限 ?只能接收extends后面的本类类型以及子类类型
public static void get1(Collection<? extends Number> collection){
}
//下限 ?只能接收super后面的本类类型以及父类类型
public static void get2(Collection<? super Number> collection){
}
}
斗地主案例(扩展)
(1)案例介绍
(2)案例分析
(3)代码演示
package com.atguiguday02.gg_poker;
/**
*
实现步骤:
1.创建集合存储花色 color
2.创建集合存储牌号 number
3.创建集合存储组合好的牌 poker
4.遍历color和number集合进行组合,存储到poker集合中
5.利用Collections.shuffle打乱poker集合
6.创建四个集合分别代表
玩家1:player1
玩家2:player2
玩家3:player3
底牌:dipai
7.让poker的索引%3,取余数,根据不同的余数,决定存储到哪个玩家集合中
8.遍历玩个玩家集合以及底牌集合
*
*
*
* **/
import java.util.ArrayList;
import java.util.Collections;
public class Poker {
public static void main(String[] args) {
//1.创建集合存储四种花色 color
ArrayList<String> color = new ArrayList<>();
color.add("♠");//黑桃
color.add("♥");//红桃
color.add("♣");//梅花
color.add("♦");//方片
//System.out.println(color);
//可以输出集合中的基础花色
//2.创建集合存储牌号 number
ArrayList<String> number = new ArrayList<>();
for (int i = 2; i <= 10; i++) {
number.add(i+"");
}//依次存入2~10花色,然后接着逐个添加进集合number
number.add("J");
number.add("Q");
number.add("K");
number.add("A");//集合添加完毕 2开始尖结束
//System.out.println(number);
//3.创建集合存储组合好的牌 poker
ArrayList<String> poker = new ArrayList<>();
//4.遍历color和number集合进行组合,存储到poker集合中
for (String s1 : color) {
for (String s2 : number) {
poker.add(s1+s2);
}
}
//System.out.println(poker);
//输出存储好的拍
poker.add("☀");//小王
poker.add("🌙");//大王
//5.利用Collections.shuffle打乱poker集合
Collections.shuffle(poker);//将存储好的排,集合直接打乱
/* 6.创建四个集合分别代表
玩家1:player1
玩家2:player2
玩家3:player3
底牌:dipai*/
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
ArrayList<String> dipai = new ArrayList<>();
//7.让poker的索引%3,取余数,根据不同的余数,决定存储到哪个玩家集合中
// //存储牌额数量
for (int i = 0; i < poker.size(); i++) {
String pai = poker.get(i);//取出集合中对应的元素
if (i>=51){//存底牌 51 52 53
dipai.add(pai);
}else if(i%3==0){//玩家1
player1.add(pai);
}else if(i%3==1){//玩家2
player2.add(pai);
}else if(i%3==2){//玩家3
player3.add(pai);
}
}
//8.遍历玩个玩家集合以及底牌集合
//对几个玩家集合进行赋名字操作
System.out.println("曼曼:"+player1);
System.out.println("涛哥:"+player2);
System.out.println("柳岩:"+player3);
System.out.println("底牌:"+dipai);
}
}
package com.atguiguday02.gg_poker;
/**
*
实现步骤:
1.创建集合存储花色 color
2.创建集合存储牌号 number
3.创建集合存储组合好的牌 poker
4.遍历color和number集合进行组合,存储到poker集合中
5.利用Collections.shuffle打乱poker集合
6.创建四个集合分别代表
玩家1:player1
玩家2:player2
玩家3:player3
底牌:dipai
7.让poker的索引%3,取余数,根据不同的余数,决定存储到哪个玩家集合中
8.遍历玩个玩家集合以及底牌集合
*
*
*
* **/
import java.util.ArrayList;
import java.util.Collections;
public class Poker {
public static void main(String[] args) {
//1.创建集合存储四种花色 color
ArrayList<String> color = new ArrayList<>();
color.add("♠");//黑桃
color.add("♥");//红桃
color.add("♣");//梅花
color.add("♦");//方片
//System.out.println(color);
//可以输出集合中的基础花色
//2.创建集合存储牌号 number
ArrayList<String> number = new ArrayList<>();
for (int i = 2; i <= 10; i++) {
number.add(i+"");
}//依次存入2~10花色,然后接着逐个添加进集合number
number.add("J");
number.add("Q");
number.add("K");
number.add("A");//集合添加完毕 2开始尖结束
//System.out.println(number);
//3.创建集合存储组合好的牌 poker
ArrayList<String> poker = new ArrayList<>();
//4.遍历color和number集合进行组合,存储到poker集合中
for (String s1 : color) {
for (String s2 : number) {
poker.add(s1+s2);
}
}
//System.out.println(poker);
//输出存储好的拍
poker.add("☀");//小王
poker.add("🌙");//大王
//5.利用Collections.shuffle打乱poker集合
Collections.shuffle(poker);//将存储好的排,集合直接打乱
/* 6.创建四个集合分别代表
玩家1:player1
玩家2:player2
玩家3:player3
底牌:dipai*/
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
ArrayList<String> dipai = new ArrayList<>();
//7.让poker的索引%3,取余数,根据不同的余数,决定存储到哪个玩家集合中
// //存储牌额数量
for (int i = 0; i < poker.size(); i++) {
String pai = poker.get(i);//取出集合中对应的元素
if (i>=51){//存底牌 51 52 53
dipai.add(pai);
}else if(i%3==0){//玩家1
player1.add(pai);
}else if(i%3==1){//玩家2
player2.add(pai);
}else if(i%3==2){//玩家3
player3.add(pai);
}
}
//8.遍历玩个玩家集合以及底牌集合
//对几个玩家集合进行赋名字操作
System.out.println("曼曼:"+player1);
System.out.println("涛哥:"+player2);
System.out.println("柳岩:"+player3);
System.out.println("底牌:"+dipai);
}
}
public class Poker2 {
public static void main(String[] args) {
//1.创建数组存储花色 color
String[] color = "♠-♥-♣-♦".split("-");
//System.out.println(color);
//2.创建数组存储牌号 number
String[] number = "2-3-4-5-6-7-8-9-10-J-Q-K-A".split("-");
//System.out.println(number);
//3.创建集合存储组合好的牌 poker
ArrayList<String> poker = new ArrayList<>();
//4.遍历color和number集合进行组合,存储到poker集合中
for (String s1 : color) {
for (String s2 : number) {
poker.add(s1+s2);
}
}
//System.out.println(poker);
poker.add("☀");
poker.add("🌙");
//5.利用Collections.shuffle打乱poker集合
Collections.shuffle(poker);
/* 6.创建四个集合分别代表
玩家1:player1
玩家2:player2
玩家3:player3
底牌:dipai*/
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
ArrayList<String> dipai = new ArrayList<>();
//7.让poker的索引%3,取余数,根据不同的余数,决定存储到哪个玩家集合中
for (int i = 0; i < poker.size(); i++) {
String pai = poker.get(i);
if (i>=51){
dipai.add(pai);
}else if(i%3==0){
player1.add(pai);
}else if(i%3==1){
player2.add(pai);
}else if(i%3==2){
player3.add(pai);
}
}
//8.遍历玩个玩家集合以及底牌集合
System.out.println("曼曼:"+player1);
System.out.println("涛哥:"+player2);
System.out.println("柳岩:"+player3);
System.out.println("底牌:"+dipai);
}
}
九、Set集合
(1)Set集合介绍
(2)HashSet集合的介绍
public class Demo01Set {
public static void main(String[] args) {
HashSet<String> set1 = new HashSet<>();
set1.add("张三");//向集合中逐个添加元素
set1.add("李四");
set1.add("王五");
set1.add("赵六");
set1.add("田七");
set1.add("张三");
System.out.println(set1);//无序,指的是存进去的时候,跟第一次取出来的不一样
System.out.println("--------------------");
//迭代器遍历
Iterator<String> iterator = set1.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("-------------------");
for (String s : set1) {
System.out.println(s);
}
}
}
(3)LinkedHashSet的介绍以及使用
public class Demo02Set {
public static void main(String[] args) {
LinkedHashSet<String> set1 = new LinkedHashSet<>();
set1.add("张三");
set1.add("李四");
set1.add("王五");
set1.add("赵六");
set1.add("田七");
set1.add("张三");
System.out.println(set1);
System.out.println("--------------------");
Iterator<String> iterator = set1.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("-------------------");
for (String s : set1) {
System.out.println(s);
}
}
}
(4)哈希值
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.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;
}
}
(5)字符串的哈希值是如何算出来的
public int hashCode() {
int h = hash; // 存储先前计算出的哈希值
if (h == 0 && value.length > 0) {
char val[] = value;
// 遍历字符串中的每个字符
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i]; // 将字符转换为整数,并与已有哈希值进行运算
}
hash = h; // 将计算得到的哈希值存储起来,以备之后的调用
}
return h; // 返回最终的哈希值
}
【计算过程】
(6)HashSet的存储去重复的过程
public class Demo01HashSet {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("abc");
set.add("通话");
set.add("重地");
set.add("abc");
System.out.println(set);
}
}
(7)HashSet存储自定义类型如何去重复
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.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 String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name) && Objects.equals(age, person.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Demo02HashSet {
public static void main(String[] args) {
HashSet<Person> set = new HashSet<>();
set.add(new Person("柳岩",36));
set.add(new Person("涛哥",18));
set.add(new Person("曼曼",48));//存储自定义对象
set.add(new Person("曼曼",48));
System.out.println(set);
}
}
十、Map集合
1)Map的介绍
2)HashMap的介绍与使用
public class Demo01HashMap {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("柳岩","涛哥");
map.put("曼曼","涛哥");
map.put("金莲","大郎");
map.put("黛玉","宝玉");
map.put("曼曼","大郎");
map.put(null,null);
System.out.println(map);
//V remove(Object key) ->根据key删除键值对,返回的是被删除的value
String value = map.remove("黛玉");
System.out.println(value);
System.out.println(map);
// V get(Object key) -> 根据key获取value
System.out.println(map.get("曼曼"));
// boolean containsKey(Object key) -> 判断集合中是否包含指定的key
System.out.println(map.containsKey("曼曼"));
//Collection<V> values() -> 获取结合中所有的value,转存到Collection集合中
Collection<String> collection = map.values();
System.out.println(collection);
}
}
public class Demo02LinkedHashMap {
public static void main(String[] args) {
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("柳岩","涛哥");
map.put("曼曼","涛哥");
map.put("金莲","大郎");
map.put("黛玉","宝玉");
map.put("曼曼","大郎");
map.put(null,null);
System.out.println(map);
}
}
3)HashMap中的两种遍历方式
(1)方式1:获取key,根据key再获取value
public class Demo03HashMap {
public static void main(String[] args) {
// 创建 HashMap 对象
HashMap<String, String> hashMap = new HashMap<>();
// 向 HashMap 中添加键值对
hashMap.put("柳岩","涛哥");
hashMap.put("金莲","大郎");
hashMap.put("丁一","乔碧萝");
hashMap.put("锟锟","丁真");
// 获取 HashMap 中所有的 key,并存入 Set 集合
Set<String> set = hashMap.keySet();
System.out.println("输出HashMap集合中的key,并存入集合Set集合");
System.out.println(set);
// 遍历 Set 集合,获取每个 key,并输出对应的 value
for (String key : set) {
String value = hashMap.get(key);
//HashMap 中根据给定的 key 获取对应的 value 值。
System.out.println(key + "..." + value);
}
//在这段代码中,通过遍历 Set 集合获取每个 key,然后使用 hashMap.get(key) 来获取对应的 value 值。
// 通过这个操作,我们可以逐个输出 HashMap 中的所有键值对
}
}
(2)方式2:同时获取key和value‘
package com.atguiguday02.kk_map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo04HashMap {
public static void main(String[] args) {
// 创建 HashMap 对象
HashMap<String, String> hashMap = new HashMap<>();
// 向 HashMap 中添加键值对
hashMap.put("柳岩","涛哥");
hashMap.put("金莲","大郎");
hashMap.put("丁一","乔碧萝");
hashMap.put("锟锟","丁真");
// 获取 HashMap 中所有的键值对,并存入 Set 集合
Set<Map.Entry<String, String>> set = hashMap.entrySet();
/**
*
* 使用 entrySet() 方法可以获取到 HashMap 中所有的键值对,
* 然后遍历 Set 集合,获取每个键值对的键和值,并输出到控制台。
* **/
// 遍历 Set 集合,获取每个键值对并输出
for (Map.Entry<String, String> entry : set) {
String key = entry.getKey(); // 获取键
String value = entry.getValue(); // 获取值
System.out.println(key + "..." + value);
}
}
}
4)HashMap存储自定义对象如何保证key唯一
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.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 String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name) && Objects.equals(age, person.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Demo05HashMap {
public static void main(String[] args) {
HashMap<Person, String> map = new HashMap<>();
map.put(new Person("柳岩",36),"湖南");
map.put(new Person("曼曼",45),"辽宁");
map.put(new Person("涛哥",18),"河北");
map.put(new Person("涛哥",18),"北京");
System.out.println(map);
}
}
5)Map的综合练习
【代码演示】
public class Demo01Map {
public static void main(String[] args) {
//1.创建Scanner对象,键盘录入一个字符串:data
Scanner sc = new Scanner(System.in);
System.out.println("请您输入一个字符串:");
String data = sc.next();
//2.创建HashMap
HashMap<String, Integer> hashMap = new HashMap<>();
//3.遍历data,将每一个元素获取出来
char[] chars = data.toCharArray();
for (char aChar : chars) {
String key = aChar+"";
//4.挨个判断,集合中是否包含指定的key
if (!hashMap.containsKey(key)){
//5.如果不包含,证明字符第一次出现,我们就将此字符和1存到集合中
hashMap.put(key,1);
}else{
//6.如果包含,根据字符获取对应的value,让value++,重新存到集合中
Integer value = hashMap.get(key);
value++;
hashMap.put(key,value);
}
}
System.out.println(hashMap);
}
}
6)斗地主(Map版本)
【代码实现】
public class Demo02Poker {
public static void main(String[] args) {
//1.创建数组,存储花色
String[] color = "♠-♥-♣-♦".split("-");
//2.创建数组,存储牌号
String[] number = "2-3-4-5-6-7-8-9-10-J-Q-K-A".split("-");
//3.创建HashMap存储牌面
HashMap<Integer, String> pokerMap = new HashMap<>();
//4.创建一个ArrayList集合,专门存储牌面对应的key
ArrayList<Integer> list = new ArrayList<>();
//5.组合牌,存储到Map集合中
int key = 2;
for (String s1 : number) {
for (String s2 : color) {
String poker = s2+s1;
pokerMap.put(key,poker);
list.add(key);
key++;
}
}
pokerMap.put(0,"大🃏");
pokerMap.put(1,"小🃏");
list.add(0);
list.add(1);
//System.out.println(pokerMap);
//6.洗牌
Collections.shuffle(list);
//7.发牌
ArrayList<Integer> player1 = new ArrayList<>();
ArrayList<Integer> player2 = new ArrayList<>();
ArrayList<Integer> player3 = new ArrayList<>();
ArrayList<Integer> dipai = new ArrayList<>();
//7.让poker的索引%3,取余数,根据不同的余数,决定存储到哪个玩家集合中
for (int i = 0; i < list.size(); i++) {
Integer pai = list.get(i);
if (i>=51){
dipai.add(pai);
}else if(i%3==0){
player1.add(pai);
}else if(i%3==1){
player2.add(pai);
}else if(i%3==2){
player3.add(pai);
}
}
//8.排序
Collections.sort(player1);
Collections.sort(player2);
Collections.sort(player3);
Collections.sort(dipai);
//9.看牌
lookPoker("柳岩",player1,pokerMap);
lookPoker("曼曼",player2,pokerMap);
lookPoker("涛哥",player3,pokerMap);
lookPoker("底牌",dipai,pokerMap);
}
public static void lookPoker(String name,ArrayList<Integer> list,HashMap<Integer, String> map){
System.out.print(name+": ");
for (Integer key : list) {
System.out.print(map.get(key)+" ");
}
System.out.println();
}
}
十一、TreeSet
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.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 String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name) && Objects.equals(age, person.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
import java.util.Comparator;
import java.util.TreeSet;
public class Demo01TreeSet {
public static void main(String[] args) {
// 创建 TreeSet 对象
TreeSet<String> treeSet = new TreeSet<>();
// 向 TreeSet 中添加元素
treeSet.add("b");
treeSet.add("d");
treeSet.add("a");
treeSet.add("c");
// 输出 TreeSet,按照自然顺序进行排序
System.out.println(treeSet);
System.out.println("================");
// 创建 TreeSet 对象,并传入自定义的 Comparator 排序器
TreeSet<Person> treeSet1 = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge(); // 按照年龄进行排序
}
});
// 向 TreeSet 中添加 Person 对象
treeSet1.add(new Person("柳岩", 36));
treeSet1.add(new Person("涛哥", 18));
treeSet1.add(new Person("曼曼", 48));
// 输出 TreeSet,按照自定义的 Comparator 排序器进行排序
System.out.println(treeSet1);
}
}
十二、TreeMap
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.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 String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name) && Objects.equals(age, person.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
package com.atguiguday03.b_tree;
import java.util.Comparator;
import java.util.TreeMap;
public class Demo02TreeMap {
public static void main(String[] args) {
// 创建 TreeMap 对象,存储字符串类型的键值对
TreeMap<String, String> treeMap = new TreeMap<>();
treeMap.put("d","低头思故乡");
treeMap.put("a","床前明月光");
treeMap.put("c","举头望明月");
treeMap.put("b","疑是地上霜");
System.out.println(treeMap);
System.out.println("================================");
// 创建 TreeMap 对象,并传入自定义的 Comparator 排序器,存储 Person 对象作为键
TreeMap<Person, String> treeMap1 = new TreeMap<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o2.getAge()-o1.getAge(); // 根据年龄降序排序
}
});
// 向 TreeMap 中添加键值对
treeMap1.put(new Person("柳岩",36),"湖南");
treeMap1.put(new Person("曼曼",48),"辽宁");
treeMap1.put(new Person("涛哥",18),"廊坊");
System.out.println(treeMap1);
}
}
十三、Hashtable和Vector集合(了解)
1)Hashtable集合
import java.util.Hashtable;
import java.util.Set;
public class Demo01Hashtable {
public static void main(String[] args) {
// 创建一个 Hashtable 对象
Hashtable<String, String> hashtable = new Hashtable<>();
// 向 Hashtable 中添加键值对
hashtable.put("张无忌","赵敏");
hashtable.put("张翠山","殷素素");
hashtable.put("张三丰","郭襄");
hashtable.put("范瑶","灭绝师太");
hashtable.put("杨逍","纪晓芙");
// 不可以存储 null 键或 null 值
// hashtable.put(null,null);
// 打印 Hashtable 的键值对
System.out.println(hashtable);
// 获取 Hashtable 中所有键的集合
Set<String> set = hashtable.keySet();
// 遍历键的集合,获取每个键对应的值并输出
for (String key : set) {
System.out.println(hashtable.get(key));
}
}
}
Hashtable和HashMap区别:
2)vector集合
package com.atguiguday03.d_vector.e_properties;
import java.util.Properties;
import java.util.Set;
public class Demo01Properties {
public static void main(String[] args) {
// 创建一个 Properties 对象
Properties properties = new Properties();
// 设置属性值
properties.setProperty("username","root");
properties.setProperty("password","root");
// 打印 Properties 对象
System.out.println(properties);
// 获取所有属性的键的集合
Set<String> set = properties.stringPropertyNames();
// 遍历键的集合,获取每个键对应的值并输出
for (String key : set) {
String value = properties.getProperty(key);
System.out.println(key + "..." + value);
}
}
}
【vector底层源码分析】
Vector()->构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零
========================================
Vector<String> vector = new Vector<>()
========================================
capacityIncrement:标准容量增强,默认为0
elementData:Vector底层数组
public Vector() {
this(10);
}
public Vector(int initialCapacity->10) {
this(initialCapacity->10, 0 -> 标准容量增量);
}
public Vector(int initialCapacity->10, int capacityIncrement->0) {
super();//不用管
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
//this.elementData = new Object[10]
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;//0
}
========================================
vector.add("a");
========================================
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1 ->11);//假如数组存了10个元素,正在存第11个
elementData[elementCount++] = e;
return true;
}
private void ensureCapacityHelper(int minCapacity->11) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity->11);//扩容相关方法
}
private void grow(int minCapacity->11) {
// overflow-conscious code
int oldCapacity = elementData.length;//10
int newCapacity = oldCapacity + ((capacityIncrement > 0)
capacityIncrement : oldCapacity);->20
//算新容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//elementData = Arrays.copyOf(老数组,20)
elementData = Arrays.copyOf(elementData, newCapacity);
}
Vector(int initialCapacity, int capacityIncrement)
==================================================
Vector<String> vector = new Vector<>(10,5);
==================================================
public Vector(int initialCapacity->10, int capacityIncrement->5) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
//this.elementData = new Object[10]
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;//5
}
===================================================
vector.add("a");
===================================================
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1->11);//假如还是超出了原始数组容量,还是存第11个
elementData[elementCount++] = e;
return true;
}
private void ensureCapacityHelper(int minCapacity->11) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity->11) {
// overflow-conscious code
int oldCapacity = elementData.length;//10
//int newCpacity = 10+5 = 15
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//elementData = Arrays.copyOf(数组,15)
elementData = Arrays.copyOf(elementData, newCapacity);
}
十四、Properties集合(属性集)
import java.util.Properties;
import java.util.Set;
public class Demo01Properties {
public static void main(String[] args) {
// 创建一个 Properties 对象
Properties properties = new Properties();
// 设置属性值
properties.setProperty("username","root");
properties.setProperty("password","1234");
// 打印 Properties 对象
System.out.println(properties);
// 获取所有属性的键的集合
Set<String> set = properties.stringPropertyNames();
// 遍历键的集合,获取每个键对应的值并输出
for (String key : set) {
String value = properties.getProperty(key);
System.out.println(key + "..." + value);
}
}
}
十五、集合嵌套
1)List嵌套List
import java.util.ArrayList;
public class Demo01ListInList {
public static void main(String[] args) {
// 创建一个ArrayList对象list1,并添加元素
ArrayList<String> list1 = new ArrayList<>();
list1.add("洪七公");
list1.add("黄老邪");
list1.add("欧阳锋");
list1.add("一灯大师");
list1.add("王重阳");
// 创建一个ArrayList对象list2,并添加元素
ArrayList<String> list2 = new ArrayList<>();
list2.add("东方不败");
list2.add("岳不群");
list2.add("林平之");
// 创建一个ArrayList对象list,将list1和list2添加进去,所以泛型要写ArrayList
ArrayList<ArrayList<String>> list = new ArrayList<>();
list.add(list1);
list.add(list2);
// 遍历list集合,将两个小集合遍历出来
for (ArrayList<String> arrayList : list) {
for (String s : arrayList) {
System.out.println(s);
}
}
}
}
2)list嵌套Map
package com.atguiguday03.e_list;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo02ListInMap {
public static void main(String[] args) {
// 创建HashMap对象map1,并添加键值对
HashMap<Integer, String> map1 = new HashMap<>();
map1.put(1,"张三");
map1.put(2,"李四");
// 创建HashMap对象map2,并添加键值对
HashMap<Integer, String> map2 = new HashMap<>();
map2.put(1,"黄晓明");
map2.put(2,"刘德华");
// 创建ArrayList对象list,将map1和map2添加进去
ArrayList<HashMap<Integer, String>> list = new ArrayList<>();
list.add(map1);
list.add(map2);
// 遍历list集合,将每个map中的键值对遍历出来
for (HashMap<Integer, String> map : list) {
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry.getKey()+"..."+entry.getValue());
}
}
}
}
会遍历就行
3)Map嵌套Map
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo03MapInMap {
public static void main(String[] args) {
// 创建HashMap对象map1,并添加键值对
HashMap<Integer, String> map1 = new HashMap<>();
map1.put(1, "张三");
map1.put(2, "李四");
// 创建HashMap对象map2,并添加键值对
HashMap<Integer, String> map2 = new HashMap<>();
map2.put(1, "黄晓明");
map2.put(2, "刘德华");
// 创建HashMap对象map,并将map1和map2添加进去
HashMap<String, HashMap<Integer, String>> map = new HashMap<>();
map.put("javase", map1);
map.put("javaee", map2);
// 获取map的键集合
Set<String> set = map.keySet();
// 遍历键集合,依次取出对应的HashMap,并遍历其中的键值对
for (String key : set) {
// 获取对应的HashMap
HashMap<Integer, String> hashMap = map.get(key);
// 获取HashMap的键值对集合
Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
// 遍历键值对集合,输出键和值
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry.getKey() + "..." + entry.getValue());
}
}
}
}
十六、哈希表的存储过程
1)HashMap无参数构造方法的分析
//HashMap中的静态成员变量
static final float DEFAULT_LOAD_FACTOR = 0.75f;
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
解析:使用无参数构造方法创建HashMap对象,将加载因子设置为默认的加载因子,loadFactor=0.75F。
2)HashMap有参数构造方法分析
HashMap(int initialCapacity, float loadFactor) ->创建Map集合的时候指定底层数组长度以及加载因子
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);//10
}
3)tableSizeFor方法分析
4)Node 内部类分析
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
5)存储元素的put方法源码
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
6)putVal方法源码
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
7)resize方法的扩容计算
if (oldCap > 0) {
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
}
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}
解析:计算结果,新的数组容量=原始数组容量<<1,也就是乘以2。
8)确定元素存储的索引
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
9)遇到重复哈希值的对象
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
解析:如果对象的哈希值相同,对象的equals方法返回true,判断为一个对象,进行覆盖操作。
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
总结:
关于集合的,我就写个这么多,写的不好的。
请指出。