(1)长度开始时必须指定,而且一旦指定,不能更改。
(2)保存的必须为同一类型的元素。
(3)使用数组进行增加元素的示意代码比较麻烦。
数组扩容,不灵活,比较麻烦,实例如下:
package com.arrayEx;
import org.junit.Test;
/**
* @author wty
* @date 2022/10/3 18:18
* 数组扩容:灵活性差,比较麻烦
*/
public class ArrayExample {
@Test
public void expandArray() {
Person[] people = new Person[3];
// 添加几个元素进去
people[0] = new Person("小明", 10);
people[1] = new Person("小刚", 20);
people[2] = new Person("小红", 30);
for (Person person : people) {
System.out.println(person);
}
System.out.println("-----------扩容后----------");
Person[] peopleAdd = new Person[5];
for (int i = 0; i < people.length; i++) {
peopleAdd[i] = people[i];
}
peopleAdd[3] = new Person("梅梅", 40);
peopleAdd[4] = new Person("兰兰", 50);
for (Person person : peopleAdd) {
System.out.println(person);
}
}
}
class Person {
private String name;
private int 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;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
(1)可以动态保存任意多个对象,使用比较方便
(2)提供了一系列方便的操作对象的方法:add、remove、set、get等
(3)使用集合添加,删除新元素更加简洁
1.集合主要是两组(单列集合、双列集合)
2.Collection接口有两个重要的子接口List Set 它们的实现子类都是单列集合
3.Map接口的实现子类 是双列集合,存放的 Key-Value
public interface Collection extends Iterable
(1)Collection实现子类可以存放多个元素,每个元素可以是Object
(2)有些Collection的实现类,可以存放重复的元素,有些不可以
(3)有些Collection的实现类是有序的(List),有些是无序的(Set)–这里说的有序和无序是指取出的顺序是否和放入顺序一致
(4)Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的
示例:
package com.CollectionExercise;
import org.junit.Test;
import java.util.*;
/**
* @author wty
* @date 2022/10/3 18:33
*/
public class CollectionExp {
@Test
@SuppressWarnings({"all"})
public void knowCollection() {
//Collection
//Map
//LinkedHashMap
//ArrayList
// 创建一个ArrayList(单列集合)
List list = new ArrayList();
// add添加单个元素
list.add("hello");
list.add(10); // list.add(new Integer(10))
list.add(true);
list.add(new Integer(30));
list.add(new String("word"));
System.out.println(list);
// remove删除元素
list.remove(0);// 删除第一个元素hello
list.remove("word"); //指定删除对象
System.out.println(list);
// contains查找某个元素是否存在
System.out.println(list.contains(true));
System.out.println(list.contains("hello"));
// size获取元素个数
System.out.println("size:" + list.size());
// isEmpty是否为空
System.out.println(list.isEmpty());
// clear清空
list.clear();
System.out.println(list);
// addAll 可以添加集合、多个元素
List list2 = new ArrayList();
list2.add(35.5d);
list2.add(45.5f);
list.addAll(list2);
System.out.println(list);
// containsAll 查找多个元素是否存在
System.out.println(list.containsAll(list2));
// removeall 删除多个元素
List list3 = new ArrayList();
list3.add("特别的爱特别的你");
list.addAll(list3);
System.out.println("removeall前:" + list);
list.removeAll(list3);
System.out.println("removeall后:" + list);
}
}
(1)Itrator对象称为迭代器,只要用于遍历Collection集合中的元素。
(2)所有实现了Collection接口的集合类都有一个Iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器
(3)Iterator仅用于遍历集合,Iterator本身并不存放对象
示例:
package com.ItratorExercise;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author wty
* @date 2022/10/4 11:45
*/
public class ItratorExercise {
@Test
@SuppressWarnings({"all"})
public void getItrator() {
Collection arrayList = new ArrayList();
arrayList.add(new Book("三国演义", "罗贯中", 42.99));
arrayList.add(new Book("西游记", "吴承恩", 38.5));
arrayList.add(new Book("水浒传", "施耐庵", 66.66));
System.out.println("直接输出:" + arrayList);
System.out.println("------------------");
// 先得到对应的迭代器
Iterator iterator = arrayList.iterator();
// 快捷键itit
// ctrl + j :所有快捷键的快捷键
while (iterator.hasNext()) { // 判断是否还有数据
// 返回下一个元素,类型是Object
Object next = iterator.next();
System.out.println(next);
}
// 当退出while循环后,这时迭代器指向最后一个元素
//报错 iterator.next(); // java.util.NoSuchElementException
// 如果希望再次遍历,需要重置迭代器
arrayList.add("今天天气不错");
System.out.println("重置迭代器之后………………");
iterator = arrayList.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
}
}
class Book {
private String name;
private String author;
private double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Book(String name, String author, double price) {
this.name = name;
this.author = author;
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
}
增强for循环,可以替代itrator迭代器,特点:增强for就是简化版的iterator,本质一样。只能用于遍历集合或者数组
基本语法:
for(元素类型 元素名:集合名或数组名){
访问元素
}
示例:
package com.StrongFor;
import org.junit.Test;
import java.util.ArrayList;
/**
* @author wty
* @date 2022/10/4 14:18
*/
public class StrongFor {
@Test
public void strongFor() {
ArrayList arrayList = new ArrayList();
arrayList.add(new Teacher("王老师", 45, 1.68));
arrayList.add(new Teacher("李老师", 25, 1.58));
arrayList.add(new Teacher("刘老师", 27, 1.78));
// 使用增强for循环,在Collection集合
// 底层仍然是迭代器
// 增强for循环,可以理解成简化版的迭代器
// I快捷键
for (Object o : arrayList) {
System.out.println(o);
}
// 增强for循环也可以在数组使用
int[] nums = {1, 8, 9, 10};
for (int num : nums) {
System.out.println(num);
}
}
}
class Teacher {
private String name;
private int age;
private double height;
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;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public Teacher(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
编写程序CollectionExercise
(1)创建3个Dog{name,age}对象,放入到ArrayList中,赋给List使用
(2)用迭代器和增强for循环两种方式来遍历
(3)重写Dog的toString方法,输出name和age
package com.CollectionAndIterator;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author wty
* @date 2022/10/4 14:33
*/
public class CollectionExerciseAndIterator {
@Test
public void cllectionExerciseAndIterator() {
List list = new ArrayList();
list.add(new Dog("大黄", 1));
list.add(new Dog("小贝", 2));
list.add(new Dog("来福", 3));
// 迭代器
System.out.println("迭代器");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
System.out.println("增强for循环");
// 增强for循环
for (Object o : list) {
System.out.println(o);
}
}
}
class Dog {
private String name;
private int 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;
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
(1)List集合类中元素有序(即添加顺序和取出顺序一致)、并且可以重复
(2)List集合中的每个元素都有其对应的顺序索引,即支持索引
(3)List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
(4)List接口的常用实现类有:ArrayList、LinkedList和Vector
List接口和常用方法
(1)add 在index位置插入元素
(2)addAll 从index位置开始将所有元素添加进来
(3)get 获取指定index位置的元素
(4)indexOf 返回在集合中首次出现的位置
(5)lastIndexOf 返回在当前集合中末次出现的位置
(6)remove 移除index位置的元素,并返回此元素
(7)set 设置指定index位置的元素(替换)
(8)subList 返回一个范围位置中的子集合
示例:
package com.ListExercise;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* @author wty
* @date 2022/10/4 15:04
*/
public class ListMethod {
@Test
public void ListMethodExercise() {
List list = new ArrayList();
list.add("张三丰");
list.add("贾宝玉");
// 插入一个元素
list.add(1, "林黛玉");
System.out.println(list);
// 插入一个集合
List list2 = new ArrayList();
list2.add("Jack");
list2.add("Tom");
list.addAll(1, list2);
System.out.println(list);
// 获取集合中索引的值
System.out.println("get(2):" + list.get(2)); // Tom
// 返回首个出现的位置
System.out.println(list.indexOf("林黛玉")); // 3
// 返回末次出现的位置
list.add("林黛玉");
System.out.println(list.lastIndexOf("林黛玉")); // 5
// 移除元素并且输出该元素
list.remove(5);
System.out.println(list);
// 替换
list.set(1, "王宝强");
System.out.println(list);
// 返回范围值内的子集合[0,3)所以只有0,1,2三个元素
List listReturn = list.subList(0, 3);
System.out.println(listReturn);
}
}
练习:
package com.ListExercise;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author wty
* @date 2022/10/4 15:17
*/
public class ListExercise02 {
@Test
public void ListExer02() {
List list = new ArrayList();
list.add("1 你好");
list.add("2 hello world");
list.add("3 10");
list.add("4 今天天气不错");
list.add("5 开心");
list.add("6 难过");
list.add("7 悲伤");
list.add("8 喜悦");
list.add("9 幸福");
list.add("10 自豪");
System.out.println(list);
list.add(1, "韩顺平教育");
System.out.println("在2号位置插入:" + list);
System.out.println("获取第5个元素:" + list.get(4));
list.remove(5);
System.out.println("删除第6个元素后:" + list);
list.set(6, "很悲伤");
System.out.println("修改第7个元素后:" + list);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
}
}
(1)方式一:使用迭代器
(2)方式二:增强for循环
(3)方式三:使用普通for循环
package com.ListExercise;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
/**
* @author wty
* @date 2022/10/4 18:08
*/
public class Bianli {
@Test
public void getBianli() {
List list = new ArrayList();
list.add("Jack");
list.add("Tom");
list.add("鱼香肉丝");
list.add("北京烤鸭");
// 迭代器遍历
System.out.println("-----迭代器遍历:-----");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
// 增强for循环遍历
System.out.println("------增强for循环遍历:-------");
for (Object o : list) {
System.out.println(o);
}
// 普通for循环遍历(类似数组)
System.out.println("-----普通for循环遍历:-------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
@Test
public void getBianli02() {
List vector = new Vector();
vector.add("Jack");
vector.add("Tom");
vector.add("鱼香肉丝");
vector.add("北京烤鸭");
// 迭代器遍历
System.out.println("-----迭代器遍历:-----");
Iterator iterator = vector.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
// 增强for循环遍历
System.out.println("------增强for循环遍历:-------");
for (Object o : vector) {
System.out.println(o);
}
// 普通for循环遍历(类似数组)
System.out.println("-----普通for循环遍历:-------");
for (int i = 0; i < vector.size(); i++) {
System.out.println(vector.get(i));
}
}
}
冒泡排序排列集合中对象的某个属性
package com.ListExercise;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* @author wty
* @date 2022/10/4 18:19
*/
public class ListExercise03 {
@Test
public void listExercise03() {
List list = new ArrayList();
list.add(new Book("红楼梦", 100, "曹雪芹"));
list.add(new Book("西游记", 10, "吴承恩"));
list.add(new Book("水浒传", 9, "施耐庵"));
list.add(new Book("三国演义", 80, "罗贯中"));
list.add(new Book("西游记", 10, "吴承恩"));
// 正常顺序
System.out.println("-----正常顺序-----");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 冒泡排序之后的顺序,从小到大
BubbleSort(list);
System.out.println("-----冒泡排序之后-------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
public void BubbleSort(List list) {
int size = list.size();
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
Object ob1 = list.get(j);
Object ob2 = list.get(j + 1);
// 向下转型
Book book1 = (Book) ob1;
Book book2 = (Book) ob2;
if (book1.getPrice() > book2.getPrice()) {
list.set(j + 1, book1);
list.set(j, book2);
}
}
}
}
}
class Book {
private String name;
private double price;
private String author;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Book(String name, double price, String author) {
this.name = name;
this.price = price;
this.author = author;
}
@Override
public String toString() {
return "名称:'" + name + '\'' +
", 价格:" + price +
", 作者:'" + author + '\'';
}
}
(1).ArrayList可以放所有的元素甚至是空元素,可以放入多个空值。
(2).ArrayList是由数组来实现数据存储的。
(3).ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高),在多线程下,不建议用ArrayList。
(4).ArrayList中维护了一个Object类型的数组elementData
transient Object[] elementData
transient:短暂的,瞬间的,表示该属性不会被序列化
(5).当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量是0,第1次添加,则扩容elementData为10,如需再次扩容,则扩容elementData为1.5倍
(6).如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍
(1)Vector类的定义说明:
public class Vector
extends AbstractList
implements List, RandomAccess, Cloneable,Serializable
(2)Vector底层也是一个对象数组,protected Object[] elementData
(3)Vector 是线程同步的,即线程安全,Vector类的操作方法带有synchronized
(4)在开发中,需要线程同步安全时,优先考虑用Vector
(1)LinkedList实现了双向链表和双端队列特点
(2)可以添加任意元素(元素可以重复),包括null
(3)线程不安全,没有实现同步
(1)LinkedList底层维护了一个双向链表
(2)LinkedList中维护了两个属性first和last分别指向首节点和尾节点
(3)每个节点(Node对象),里面又维护了prev,next,item三个属性,其中通过prev指向前一个,通过next指向后一个节点 ,最终实现双向链表。
(4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高
模拟一个双向链表简单示例:
package com.ListExercise;
import org.junit.Test;
/**
* @author wty
* @date 2022/10/6 14:45
* 模拟一个双向链表
*/
public class LinkedListExercise02 {
@Test
public void getLinked() {
Linked one = new Linked("One");
Linked two = new Linked("Two");
Linked four = new Linked("Four");
one.next = two;
two.next = four;
four.pre = two;
two.pre = one;
Linked first = one; // 定义头结点
System.out.println("----从头到尾遍历-----");
while (true) {
if (first == null) {
break;
}
System.out.println(first);
first = first.next;
}
Linked last = four; // 定义尾结点
System.out.println("----从尾到头遍历-----");
while (true) {
if (last == null) {
break;
}
System.out.println(last);
last = last.pre;
}
// 插入一个元素
Linked three = new Linked("Three");
two.next = three;
four.pre = three;
three.next = four;
three.pre = two;
first = one;
System.out.println("插入元素3之后,从头到尾遍历");
while (true) {
if (null == first) {
break;
}
System.out.println(first);
first = first.next;
}
last = four;
System.out.println("插入元素3之后,从尾到头遍历");
while (true) {
if (null == last) {
break;
}
System.out.println(last);
last = last.pre;
}
}
}
class Linked {
public Linked pre;
public Linked next;
public Object name;
public Linked(Object name) {
this.name = name;
}
@Override
public String toString() {
return "Linked{" +
"name=" + name +
'}';
}
}
关于LinkedList源码分析
package com.ListExercise;
import org.junit.Test;
import java.util.Iterator;
import java.util.LinkedList;
/**
* @author wty
* @date 2022/10/6 15:01
*/
public class LinkedListCRUD {
@Test
public void linkedListCRUD() {
LinkedList list = new LinkedList();
list.add(100);
list.add(200);
list.add(300);
System.out.println(list);
// 修改,把200更改成400
System.out.println(list.set(1, 400)); // 200
// 删除400
System.out.println(list.remove(1)); // 400
// 查找第2个元素
System.out.println(list.get(1));
// 迭代器遍历
System.out.println("----迭代器遍历----");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
System.out.println("增强for循环遍历");
for (Object o : list) {
System.out.println(o);
}
System.out.println("普通for循环遍历");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
(1)无序(添加和取出的顺序不一致),没有索引
(2)不允许元素重复,所以最多包含一个null
(3)JDK API中Set接口的实现类有:
同Collection的遍历方式一样,因为Set接口是Collection接口的子接口。
1.可以使用迭代器
2.增强for循环
3.不能使用索引的方式来获取
常用方法示例;
package com.SetExercise;
import org.junit.Test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* @author wty
* @date 2022/10/6 17:24
*/
public class SetMethod {
@Test
public void SetMethodEx() {
// 以Set接口的实现类,HashSet为例
// Set接口的实现类的对象(Set接口对象)不能存放重复元素
// 可以添加一个null
// Set接口对象存放数据、对象是无序的(添加顺序和取出顺序不一致)
// 取出的顺序是固定的
Set set = new HashSet();
set.add("小明");
set.add("小芳");
set.add("小刚");
set.add("小明");
set.add(null);
set.add(null);
System.out.println(set);
// 遍历
//方式1;迭代器
System.out.println("---迭代器---");
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
// 增强for循环
System.out.println("---增强for循环---");
for (Object o : set) {
System.out.println(o);
}
System.out.println("size:" + set.size());
System.out.println("是否为空:" + set.isEmpty());
System.out.println("是否包含元素[小刚]:" + set.contains("小刚"));
System.out.println("remove:" + set.remove("小刚"));
System.out.println("remove:" + set.remove(null));
System.out.println(set);
}
}
(1)HashSet实现了Set接口
(2)HashSet实际上是HashMap
(3)可以存放null值,但是只能有一个null
(4)HashSet不保证元素是有序的,取决于hash后,再确定索引的结果(不保证元素存放和取出顺序一致)
(5)不能有重复元素/对象。在前面Set接口使用已经讲过了
package com.SetExercise;
import org.junit.Test;
/**
* @author wty
* @date 2022/10/6 18:14
*/
public class HashSetStructure {
@Test
public void getHashSetStr(){
// 模拟一个HashSet的底层(其实就是HashMap)
// 创建一个Node数组,有些人称为table
Node[] table = new Node[16];
System.out.println("table:" + table);
// 把john放在2的位置
Node jhon = new Node("Jhon",null);
table[2] = jhon;
System.out.println("table:" + table);
Node jack = new Node("Jack", null);
jhon.next = jack; // 将jack挂载到johj后边
System.out.println("table:" + table);
// 继续把Rose挂载到Jack后面
Node rose = new Node("Rose", null);
jack.next = rose;
System.out.println("table:" + table);
// 把Lucy放到table表索引为3的位置
Node lucy = new Node("Lucy", null);
table[3] = lucy;
}
}
// 结点,存储数据,可以指向下一个结点
class Node{
Object item;// 存放数据
Node next; // 指向下一个结点
public Node(Object item, Node next) {
this.item = item;
this.next = next;
}
}
分析:HashSet底层是HashMap,HashMap底层是(数组+链表+红黑树)
浓缩成6句话
package com.SetExercise;
import org.junit.Test;
import java.util.HashSet;
import java.util.Objects;
/**
* @author wty
* @date 2022/10/7 14:50
*/
public class Employee {
@Test
public void employee() {
HashSet hashSet = new HashSet();
hashSet.add(new Workers("小明", 10));
hashSet.add(new Workers("小红", 20));
hashSet.add(new Workers("小明", 30));
hashSet.add(new Workers("小刚", 40));
hashSet.add(new Workers("小明", 10));
System.out.println("size:" + hashSet.size());
System.out.println(hashSet);
}
}
class Workers {
private String name;
private int age;
public Workers(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Workers{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// 如果name和age相同,要返回相同的哈希值
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Workers workers = (Workers) o;
return Objects.equals(name, workers.name) && this.age == workers.age;
}
/* @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Workers workers = (Workers) o;
return age == workers.age && Objects.equals(name, workers.name);
}*/
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
equals和hashCode示例2:重写2次
package com.SetExercise;
import org.junit.Test;
import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
/**
* @author 心向阳光的天域
* @date 2022/10/7 15:19
*/
public class Employee02 {
@Test
public void getPerson() {
HashSet hashSet = new HashSet();
hashSet.add(new Employ("小明", 10000.88d, new MyDate("1996", "01", "01")));
// 姓名一样,出生年份不同
hashSet.add(new Employ("小明", 10001.88d, new MyDate("1997", "01", "01")));
// 出生年份和工资不同
hashSet.add(new Employ("小明", 10001.88d, new MyDate("1998", "01", "01")));
// 工资和第一个比不同(按照规则,这个应该不展示)
hashSet.add(new Employ("小明", 10002.88d, new MyDate("1996", "01", "01")));
// 重写了toString()方法,这里可以遍历一下,看看值
System.out.println("size:" + hashSet.size());
for (Object o : hashSet) {
System.out.println(o);
}
}
}
class Employ {
private String name;
private double sal;
private MyDate birthday;
public Employ(String name, double sal, MyDate birthday) {
this.name = name;
this.sal = sal;
this.birthday = birthday;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employ employ = (Employ) o;
return Objects.equals(name, employ.name) && Objects.equals(birthday, employ.birthday);
}
@Override
public int hashCode() {
return Objects.hash(name, birthday);
}
@Override
public String toString() {
return "Employ{" +
"name='" + name + '\'' +
", sal=" + sal +
", birthday=" + birthday +
'}';
}
}
class MyDate {
String year;
String month;
String day;
public MyDate(String year, String month, String day) {
this.year = year;
this.month = month;
this.day = day;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyDate myDate = (MyDate) o;
return Objects.equals(year, myDate.year) && Objects.equals(month, myDate.month) && Objects.equals(day, myDate.day);
}
@Override
public int hashCode() {
return Objects.hash(year, month, day);
}
@Override
public String toString() {
return "MyDate{" +
"year='" + year + '\'' +
", month='" + month + '\'' +
", day='" + day + '\'' +
'}';
}
}
equals和hashCode示例2:重写1次
package com.SetExercise;
import org.junit.Test;
import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
/**
* @author 心向阳光的天域
* @date 2022/10/7 15:19
*/
public class Employee03 {
@Test
public void getPerson() {
HashSet hashSet = new HashSet();
hashSet.add(new Employ("小明", 10000.88d, new MyDate("1996", "01", "01")));
hashSet.add(new Employ("小明", 10001.88d, new MyDate("1997", "01", "01")));
hashSet.add(new Employ("小明", 10001.88d, new MyDate("1998", "01", "01")));
// 按照重复数据去重
hashSet.add(new Employ("小明", 10002.88d, new MyDate("1996", "01", "01")));
System.out.println("size:" + hashSet.size());
for (Object o : hashSet) {
System.out.println(o);
}
}
}
class Employ02 {
private String name;
private double sal;
private MyDate02 birthday;
public Employ02(String name, double sal, MyDate02 birthday) {
this.name = name;
this.sal = sal;
this.birthday = birthday;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employ02 employ = (Employ02) o;
return Objects.equals(name, employ.name)
// 这里直接重写一次equals方法即可
&& Objects.equals(birthday.getYear(), employ.birthday.getYear())
&& Objects.equals(birthday.getMonth(), employ.birthday.getMonth())
&& Objects.equals(birthday.getDay(), employ.birthday.getDay());
}
@Override
public int hashCode() {
// 这里直接重写一次hashCode方法即可
return Objects.hash(name, birthday.year, birthday.month, birthday.day);
}
@Override
public String toString() {
return "Employ{" +
"name='" + name + '\'' +
", sal=" + sal +
", birthday=" + birthday +
'}';
}
}
class MyDate02 {
String year;
String month;
String day;
public MyDate02(String year, String month, String day) {
this.year = year;
this.month = month;
this.day = day;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
@Override
public String toString() {
return "MyDate{" +
"year='" + year + '\'' +
", month='" + month + '\'' +
", day='" + day + '\'' +
'}';
}
}
LinkedHashSet的全面说明
(1)LinkedHashSet是HashSet的子类
(2)LinkedHashSet底层是一个LinkedHashMap,底层维护了一个数组+双向链表+红黑树
(3)LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序图(图),这使得元素看起来是以插入顺序保存的。
(4)LinkedHashSet不允许添加重复元素
说明:
在LinkedHashSet中维护一个hash表和双向链表(LinkedHashSet 有head和tail)
每一个结点有before和after属性,这样可以形成双向链表
在添加一个元素时,先求hash值,再求索引,确定该元素在table的位置,然后将添加的元素加入到双向链表(如果已经存在,不添加[原则和hashset一样])
tail.next = newElement
newElement.pre = tail
tail = newElement;
这样的话,我们遍历LinkedHashSet 也能确保插入顺序和遍历顺序一致
equals和hashCode重写
package com.SetExercise;
import org.junit.Test;
import java.util.LinkedHashSet;
import java.util.Objects;
/**
* @author wty
* @date 2022/10/8 19:57
* 如果name和price一样就认为是一样的元素
*/
public class LinkedHashSetExercise01 {
@Test
public void getHashSet() {
LinkedHashSet set = new LinkedHashSet();
set.add(new Car("奥迪", 1000d));
set.add(new Car("奥迪", 30000d));
set.add(new Car("法拉利", 100000d));
set.add(new Car("保时捷", 7000000d));
set.add(new Car("奥迪", 1000d));
for (Object o : set) {
System.out.println(o);
}
}
}
class Car {
private String name;
private double price;
public Car(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
// 重写equals和hash方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return Double.compare(car.price, price) == 0 && Objects.equals(name, car.name);
}
@Override
public int hashCode() {
return Objects.hash(name, price);
}
}
(1)Map与Collection并列存在,用于保存具有映射关系的数据Key-Value(双列元素)
(2)Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
(3)Map中的key不允许重复,原因和HashSet一样,前面分析过源码。
(4)Map中的value可以重复
(5)Map的key可以为null,value也可以为null,注意key为null,只能有一个,value为null可以多个
(6)常用String类作为Map的key
(7)key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value
(8)Map存放数据的key-value示意图,一对key-value 是放在一个Node中的,又因为Node实现了Entry接口,有些书上也说一对key-value就是一个Entry(如图)
package com.Map;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* @author wty
* @date 2022/10/8 22:45
*/
public class MapExercise {
@Test
public void getExercise() {
// Map接口具有的特点
// 常用String类作为Map的key
Map hashMap = new HashMap();
hashMap.put("1", "Jack");
hashMap.put("2", 10);
hashMap.put("3", "贾斯汀比伯");
hashMap.put("4", "迈克尔杰克逊");
hashMap.put("5", "贾斯汀比伯");
hashMap.put("6", "Alice");
hashMap.put("7", "VERTGA");
hashMap.put("8", "LAM");
hashMap.put("9", "GIN");
hashMap.put("10", "TIO");
hashMap.put("11", "AIO");
hashMap.put("12", "Tony");
hashMap.put("13", "Joy");
hashMap.put("1", "Rose"); // 替换机制:当有相同key值时。就替换
hashMap.put(null, null);
hashMap.put(null, null); // Map的key可以为null,value也可以为null,注意key为null,只能有一个,value为null可以多个
hashMap.put("17", null);
hashMap.put(null, 181); // 替换
hashMap.put(1, "Jack"); // key可以用别的类型
System.out.println(hashMap);
System.out.println("get(1):" + hashMap.get(1));
}
}
entrySet()获取entrySet,entrySet是一个Set
(1)put:添加
(2)remove:根据键删除映射关系
(3)get:根据键获取值
(4)size:获取元素个数
(5)isEmpty:判断个数是否为0
(6)clear:清除
(7)containsKey:查找键是否存在
package com.Map;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* @author wty
* @date 2022/10/9 9:02
*/
public class MapUse {
@Test
public void mapUse() {
/**
* (1)put:添加
* (2)remove:根据键删除映射关系
* (3)get:根据键获取值
* (4)size:获取元素个数
* (5)isEmpty:判断个数是否为0
* (6)clear:清除
* (7)containsKey:查找键是否存在
*/
Map map = new HashMap();
map.put("1", "Book");
map.put("邓超", "孙俪");
map.put("马蓉", "王宝强");
map.put("马蓉", "宋喆");
System.out.println(map);
map.remove("1");
System.out.println(map);
System.out.println(map.get("邓超"));
System.out.println("size:" + map.size());
System.out.println("是否为空:" + map.isEmpty());
System.out.println("有没有马蓉: " + map.containsKey("马蓉"));
map.clear();
System.out.println("clean之后" + map);
}
}
Map遍历的示意图(比List,和Set复杂一点,但是基本原理一样)
(1)containsKey:查找键是否存在
(2)keySet:获取所有的键
(3)entrySet:获取所有关系
(4)values:获取所有的值
package com.Map;
import org.junit.Test;
import java.util.*;
/**
* @author wty
* @date 2022/10/9 9:15
*/
public class MapBl {
@Test
public void Mapbl() {
Map map = new HashMap();
map.put("1", "Jack");
map.put("上单", "老夫子");
map.put("中单", "诸葛亮");
map.put("射手", "后裔");
System.out.println(map);
// 遍历(自己想的)
System.out.println("----增强for循环----");
Set set = map.entrySet();
for (Object o : set) {
System.out.println(o);
}
// 遍历(自己想的)
System.out.println("----迭代器----");
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
// 韩老师讲的
// 1. 先取出所有的key,通过key找到对应的value
System.out.println("----map.keySet()----");
Set keyset = map.keySet();
for (Object o : keyset) {
// 向下转型
System.out.println("key = " + o + " value = " + map.get(o));
}
// 2.通过迭代器
System.out.println("----map.keySet()的迭代器----");
Iterator iterator1 = keyset.iterator();
while (iterator1.hasNext()) {
Object next = iterator1.next();
System.out.println("key = " + next + " value = " + map.get(next));
}
// 3.只是把所有的values取出
System.out.println("----map.values()----");
Collection values = map.values();
for (Object value : values) {
System.out.println("value = " + value);
}
System.out.println("----map.values()迭代器----");
Iterator iterator2 = values.iterator();
while (iterator2.hasNext()) {
Object next = iterator2.next();
System.out.println("value = " + next);
}
// 3.通过EntrySet
// 增强for循环
System.out.println("----map.entrySet()增强for循环----");
Set entryset = map.entrySet();
for (Object o : entryset) {
Map.Entry entry = (Map.Entry) o;
System.out.println("key = " + entry.getKey() + " value = " + entry.getValue());
}
// 通过迭代器
System.out.println("----entrySet迭代器----");
Set entrySet = map.entrySet();
Iterator iterator3 = entrySet.iterator();
while (iterator3.hasNext()) {
Object next = iterator3.next();
//System.out.println(next.getClass()); // HashMap$Node
Map.Entry entry = (Map.Entry) next;
System.out.println("key = " + entry.getKey() + " value = " + entry.getValue());
}
}
}
package com.Map;
import org.junit.Test;
import java.util.*;
/**
* @author wty
* @date 2022/10/9 12:41
*/
public class AfterClassExercise {
@Test
public void showWorkers() {
/*HashSet hashSet = new HashSet();
hashSet.add(new Workers("王晓亮", 15000.5, "no.1"));
hashSet.add(new Workers("钟飞扬", 16060.5, "no.2"));
hashSet.add(new Workers("潘长江", 18060.5, "no.3"));
hashSet.add(new Workers("小悦悦", 27060.5, "no.4"));
System.out.println(hashSet);
for (Object o : hashSet) {
Map.Entry entry = (Map.Entry) o;
entry.getKey();
}*/
HashMap hashMap = new HashMap();
hashMap.put("no.1", new Workers("王晓亮", 15000.5, "no.1"));
hashMap.put("no.2", new Workers("钟飞扬", 16060.5, "no.2"));
hashMap.put("no.3", new Workers("潘长江", 18060.5, "no.3"));
hashMap.put("no.4", new Workers("小悦悦", 27060.5, "no.4"));
hashMap.put("no.5", "Jack");
// 显示工资大于18000的人
System.out.println("-----------------keySet()------------------");
Set set = hashMap.keySet();
for (Object o : set) { // String
//System.out.println(o.getClass());
if (hashMap.get(o) instanceof Workers) {
Workers workers = (Workers) hashMap.get(o); // hashMap.get(o) 是对象Workers
if (workers.getSal() > 18000) {
System.out.println("key = " + o + " value = " + hashMap.get(o));
}
} else {
System.out.println("key = " + o + " value = " + hashMap.get(o));
}
}
// 迭代器
System.out.println("-----------------keySet()迭代器------------------");
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
if (hashMap.get(next) instanceof Workers) {
Workers workers = (Workers) hashMap.get(next);
if (workers.getSal() > 18000) {
System.out.println("key = " + next + " value = " + hashMap.get(next));
}
} else {
System.out.println("key = " + next + " value = " + hashMap.get(next));
}
}
// 使用entrySet()方法
System.out.println("-----------entrySet()增强for循环-----------");
Set set1 = hashMap.entrySet();
for (Object o : set1) {
Map.Entry entry = (Map.Entry) o;
if (entry.getValue() instanceof Workers) {
Workers workers = (Workers) entry.getValue();
if (workers.getSal() > 18000) {
System.out.println("key = " + entry.getKey() + " value = " + entry.getValue());
}
} else {
System.out.println("key = " + entry.getKey() + " value = " + entry.getValue());
}
}
}
}
class Workers {
private String name;
private double sal;
String id;
public Workers(String name, double sal, String id) {
this.name = name;
this.sal = sal;
this.id = id;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
@Override
public String toString() {
return "Workers{" +
"name='" + name + '\'' +
", sal=" + sal +
", id=" + id +
'}';
}
}
(1)HashMap底层维护了Node类型的数组table,默认为null
(2)当创建对象时,将加载因子(loadFactor)初始化为0.75
(3)当添加key-value时,通过key的哈希值得到在table的索引。然后判断该索引处是否有元素,如果没有元素,则直接添加。如果该处索引有元素,则继续判断该元素的key是否和准备加入的key相等,如果相等,则直接替换成新的val,如果不相等,需要判断是树结构还是链表结构,做出相应的处理。如果添加时发现容量不够,则需要扩容。
(4)第1次添加,则需要扩容table容量为16,临界值(threshold)为12
(5)以后再扩容,则需要扩容table容量为原来的2倍,临界值为原来的2倍,即24,以此类推。
(6)在Java8中,如果一条链表的元素个数超过了TREEIFY_THRESHOLD(默认是8),并且table的大小>= MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)
package com.Map;
import org.junit.Test;
import java.util.*;
/**
* @author wty
* @date 2022/10/9 16:41
*/
public class HashMapSource {
@Test
public void getSource() {
HashMap hashMap = new HashMap();
//HashSet hashSet = new HashSet();
//LinkedHashSet linkedHashSet = new LinkedHashSet();
hashMap.put(new Cat("小红", 1) , "no1.Jack");
hashMap.put(new Cat("小红", 2) , "no2.Jack");
hashMap.put(new Cat("小红", 3) , "no3.Jack");
hashMap.put(new Cat("小红", 4) , "no4.Jack");
hashMap.put(new Cat("小红" ,5) , "no5.Jack");
hashMap.put(new Cat("小红", 6) , "no6.Jack");
hashMap.put(new Cat("小红", 7) , "no7.Jack");
hashMap.put(new Cat("小红", 8) , "no8.Jack");
/**
* // 从第二次put之后才会进这里,并且第二次循环时 var12 0 第二次循环结束 var12 1 -- 即第三次循环开始 var12 1
* 所以var12比put的次数少2,一直到put第9的时候,var12 >= 7才会满足
* while(true) {
* if ((var10 = ((HashMap.Node)var7).next) == null) {
* ((HashMap.Node)var7).next = this.newNode(var1, var2, var3, (HashMap.Node)null);
* if (var12 >= 7) {
* this.treeifyBin(var6, var1);
* }
* break;
* }
*
* if (((HashMap.Node)var10).hash == var1 && ((var11 = ((HashMap.Node)var10).key) == var2 || var2 != null && var2.equals(var11))) {
* break;
* }
*
* var7 = var10;
* ++var12;
* }
*/
hashMap.put(new Cat("小红", 9) , "no9.Jack");
hashMap.put(new Cat("小红", 10) , "no10.Jack");
hashMap.put(new Cat("小红", 11) , "no11.Jack");
hashMap.put(new Cat("小红", 12) , "no12.Jack");
/**
* if (++this.size > this.threshold) { 所以是第13次put的时候扩容 16 → 32
* this.resize();
* }
*/
hashMap.put(new Cat("小红", 13) , "no13.Jack"); //
hashMap.put(new Cat("小红", 14) , "no14.Jack");
hashMap.put(new Cat("小蓝", 9) , "no9.Jack"); // 扩容table 32
hashMap.put(new Cat("小蓝", 10) , "no10.Jack"); // 扩容table 64
hashMap.put(new Cat("小蓝", 11) , "no11.Jack"); // 将链表转换成红黑树
//hashMap.put("11", "no111.Jack");
//hashMap.put("12", "no12.Jack");
//hashMap.put("13", "no13.Jack"); // 超过12才扩容
/* hashMap.remove(new Cat("小蓝", 11));
hashMap.remove(new Cat("小蓝", 10));
hashMap.remove(new Cat("小蓝", 9));
hashMap.remove(new Cat("小红", 8));
hashMap.remove(new Cat("小红", 7));
hashMap.remove(new Cat("小红", 6));
hashMap.remove(new Cat("小红", 5));
hashMap.remove(new Cat("小红", 4)); // 执行完之后剪枝
hashMap.remove(new Cat("小红", 3));
hashMap.remove(new Cat("小红", 3));*/
Set set = hashMap.keySet();
for (Object o : set) {
System.out.println("key = " + o + " value = " + hashMap.get(o));
}
System.out.println(hashMap);
}
}
class Cat {
private String name;
private int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int hashCode() {
return Objects.hash(100);
}
}
(1)存放的元素是键值对:即K-V
(2)hashtable的键和值都不能为null,否则会抛出NullPointerException
(3)hashTable使用方法基本上和HashMap一样
(4)hashTable是线程安全的(synchronized),hashMap是线程不安全的
(5)实现Map接口
注意:
Hashtable和HashMap对比
名称 | 版本 | 线程安全(同步) | 效率 | 允许null键null值 |
---|---|---|---|---|
Hashtable | 1.2 | 不安全 | 高 | 可以 |
HashMap | 1.0 | 安全 | 较低 | 不可以 |
基本介绍
配置文件不会显示乱码,统一调整为UTF-8
PropertiesEx.java
package com.Map.Properties;
import org.junit.Test;
import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/**
* @author wty
* @date 2022/10/9 23:49
*/
public class PropertiesEx {
@Test
public void propertiesEx() {
Properties properties = new Properties();
String path = "src/com/Map/File/res.properties";
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
bufferedReader = new BufferedReader(new FileReader(path));
properties.load(bufferedReader);
Set<Map.Entry<Object, Object>> entries = properties.entrySet();
Iterator<Map.Entry<Object, Object>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<Object, Object> next = iterator.next();
System.out.println("key = " + next.getKey() + " value = " + next.getValue());
}
// 写入
bufferedWriter = new BufferedWriter(new FileWriter(path));
properties.setProperty("signature", "rose");
properties.setProperty("signature", "厉害");
properties.store(bufferedWriter, "This is my destney哈哈");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedReader.close();
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
res.properties
name=root
key=value
pass=liu
基本用法
package com.Map.Properties;
import org.junit.Test;
import java.util.Properties;
/**
* @author wty
* @date 2022/10/10 9:46
*/
public class PropertiesExercise {
@Test
public void getEx() {
Properties properties = new Properties();
properties.put("no.1", "Jack");
properties.put("no.2", "Jone");
// 有相同的key,value会被替换
properties.put("no.2", "Joy");
//properties.put(null,null); // java.lang.NullPointerException
// 键不能为空
//properties.put(null,"1"); // java.lang.NullPointerException
// 值不能为空
//properties.put("no.3",null); // java.lang.NullPointerException
properties.put("no.3", "Rose");
System.out.println(properties);
// 通过key获取对应的值
System.out.println("no.2: " + properties.get("no.2"));
properties.remove("no.3");
System.out.println("删除no.3之后");
System.out.println(properties);
// 修改:
properties.setProperty("no.2", "Alice");
System.out.println("setProperty修改no.2之后");
System.out.println(properties);
properties.put("no.2", "Rice");
System.out.println("putno.2之后");
System.out.println(properties);
// 查找
System.out.println("getProperty no.1之后");
System.out.println(properties.getProperty("no.1"));
}
}
在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行选择,分析如下:
(1)先判断存储类型(一组对象(单列)或者键值对(双列))
(2)一组对象: Collection接口
允许重复:List
增删多:LinkedList(底层是双向链表)
查改多:ArrayList(底层维护Object类型的可变数组)
不允许重复:Set
无序:HashSet底层是HashMap,维护一个Hash表(数组+链表+红黑树)
排序:TreeSet
插入和取出顺序一样: LinkedHashSet(继承自LinkedHashMap),维护数组+双向链表
(3)键值对:Map
键无序:HashMap(底层是:哈希表:数组+链表+红黑树)
键有序:TreeMap
键插入和取出顺序一致:LinkedHashMap(继承自HashMap)
读取文件: Properties
TreeSet含Comparator构造器
package com.SetExercise;
import org.junit.Test;
import java.util.Comparator;
import java.util.TreeSet;
/**
* @author wty
* @date 2022/10/10 10:20
*/
public class TreeSetExercise {
@Test
@SuppressWarnings({"all"})
public void getTreeSet() {
// 当使用无参构造器创建TreeSet的时候是无序的
TreeSet treeSet = new TreeSet();
// 添加数据
treeSet.add("Derrick");
treeSet.add("Rose");
treeSet.add("Jam");
treeSet.add("Timmy");
treeSet.add("Tom");
System.out.println(treeSet);
System.out.println("---字符串按照首字母顺序比较---");
// 添加的元素按照字符串大小来排序
// 可以传入一个比较器(匿名内部类),并指定规则
TreeSet treeSet1 = new TreeSet(new Comparator() {
@Override
public int compare(Object o, Object t1) {
return ((String) o).compareTo((String) t1);
}
});
treeSet1.add("Derrick");
treeSet1.add("Rose");
treeSet1.add("Jam");
treeSet1.add("Timmy");
treeSet1.add("Tom");
System.out.println(treeSet1);
// 源码解读
/**
* public TreeMap(Comparator super K> var1) {
* this.comparator = var1; 把new Comparator() 给到TreeMap的comparator属性
* }
*/
System.out.println("---字符串长度大小比较---");
TreeSet treeSet2 = new TreeSet(new Comparator() {
@Override
public int compare(Object o, Object t1) {
String str_a = (String) o;
String str_t1 = (String) t1;
int a = ((String) o).length();
int b = ((String) t1).length();
int result = a - b;
return result = result == 0 ? str_a.compareTo(str_t1) : result;
}
});
treeSet2.add("Derrick");
treeSet2.add("Amy");
treeSet2.add("Rose");
treeSet2.add("Jam"); // 相同长度加不进去
treeSet2.add("Timmy");
treeSet2.add("Tom");// 相同长度加不进去
System.out.println(treeSet2);
}
}
package com.Map;
import org.junit.Test;
import java.util.Comparator;
import java.util.TreeMap;
/**
* @author wty
* @date 2022/10/10 12:33
*/
public class TreeMapExercise {
@Test
public void getTreeMap() {
// 无参数,无序取出
TreeMap treeMap = new TreeMap();
treeMap.put("1", "Jack");
treeMap.put("no2", "Tom");
treeMap.put("李小璐", "PGONE");
treeMap.put("smith", "史密斯");
System.out.println(treeMap);
// 按照key字符串首字母倒叙排序
TreeMap treeMap2 = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String) o2).compareTo((String) o1);
}
});
System.out.println("按照key字符串首字母倒叙排序");
treeMap2.put("1", "Jack");
treeMap2.put("no2", "Tom");
treeMap2.put("李小璐", "PGONE");
treeMap2.put("smith", "史密斯");
treeMap2.put("alice", "漫游记");
System.out.println(treeMap2);
// 按照key字符串长度排序,相同长度按首字母倒叙排序
TreeMap treeMap3 = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String str_o1 = (String) o1;
String str_o2 = (String) o2;
int a = str_o1.length();
int b = str_o2.length();
int result = a == b ? str_o1.compareTo(str_o2) : a - b;
return result;
}
});
System.out.println("按照key字符串长度排序,相同长度按首字母顺叙排序");
treeMap3.put("1", "Jack");
treeMap3.put("no2", "Tom");
treeMap3.put("李小璐", "PGONE");
treeMap3.put("smith", "史密斯");
treeMap3.put("alice", "漫游记");
treeMap3.put("tonny", "理发师");
System.out.println(treeMap3);
}
}
Collections工具类介绍
(1)Collections是一个操作Set、List和Map等集合的工具类
(2)Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改操作
(1)reverse(List):反转List中元素的顺序
(2)shuffle(List):对List集合元素进行随机排序
(3)sort(List):根据元素的自然顺序对指定List集合元素按升序排序
(4)sort(List,Comparator):根据指定的Comparator产生的顺序对List集合进行排序
(5)swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
package com.CollectionsUse;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
/**
* @author wty
* @date 2022/10/10 14:57
*/
public class CollectionsUse {
@Test
public void getUse() {
HashMap hashMap = new HashMap();
hashMap.put("Jack", "Rose");
hashMap.put("no.1", "Tony");
hashMap.put("no.2", "Jancy");
hashMap.put("This", "is my destney");
/**
* (1)reverse(List):反转List中元素的顺序
* (2)shuffle(List):对List集合元素进行随机排序
* (3)sort(List):根据元素的自然顺序对指定List集合元素按升序排序
* (4)sort(List,Comparator):根据指定的Comparator产生的顺序对List集合进行排序
* (5)swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
*/
System.out.println(hashMap);
ArrayList arrayList = new ArrayList();
arrayList.add("Derrick");
arrayList.add("Rose");
arrayList.add("no.1");
arrayList.add("2");
arrayList.add("周润发");
arrayList.add("周杰伦");
arrayList.add("洪辰");
System.out.println("----正常-----");
System.out.println(arrayList);
Collections.reverse(arrayList); // (1)reverse(List):反转List中元素的顺序
System.out.println("----倒叙----");
System.out.println(arrayList);
System.out.println("----随机顺序----");
Collections.shuffle(arrayList); // (2)shuffle(List):对List集合元素进行随机排序
System.out.println(arrayList);
System.out.println("----再次随机顺序----");
Collections.shuffle(arrayList);
System.out.println(arrayList);
System.out.println("----自然排序----"); // 根据元素的自然顺序对指定List集合元素按升序排序
Collections.sort(arrayList);
System.out.println(arrayList);
// sort(List,Comparator):根据指定的Comparator产生的顺序对List集合进行排序
System.out.println("----自然排序Comparator:按照字符串长度大小排序----");
Collections.sort(arrayList, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof String && o2 instanceof String) {
String str_o1 = (String) o1;
String str_o2 = (String) o2;
int a = str_o1.length();
int b = str_o2.length();
int result = a == b ? str_o1.compareTo(str_o2) : a - b;
return result;
} else {
return 0;
}
}
});
System.out.println(arrayList);
// (5)swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
System.out.println("----交换第一个和第三个元素----");
Collections.swap(arrayList, 0, 2);
System.out.println(arrayList);
}
}
(1)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
(2)Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素
(3)Object min(Collection)
(4)Object min(Collection, Object)
(5)int frequency(Collection, Object):返回指定集合中指定元素的出现次数
(6)void copy(List dest, List src):将src中的内容复制到dest中
(7)boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值
@Test
public void getUseCollections() {
/**
* (1)reverse(List):反转List中元素的顺序
* (2)shuffle(List):对List集合元素进行随机排序
* (3)sort(List):根据元素的自然顺序对指定List集合元素按升序排序
* (4)sort(List,Comparator):根据指定的Comparator产生的顺序对List集合进行排序
* (5)swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
*/
ArrayList arrayList = new ArrayList();
arrayList.add("Derrick");
arrayList.add("Rose");
arrayList.add("no.1");
arrayList.add("2");
arrayList.add("周润发");
arrayList.add("周杰伦");
arrayList.add("洪辰");
arrayList.add("Rose");
System.out.println("----正常-----");
System.out.println(arrayList);
/**
* (1)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
* (2)Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素
* (3)Object min(Collection)
* (4)Object min(Collection, Object)
* (5)int frequency(Collection, Object):返回指定集合中指定元素的出现次数
* (6)void copy(List dest, List src):将src中的内容复制到dest中
* (7)boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值
*/
// (1)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
System.out.println("Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素");
System.out.println(Collections.max(arrayList));
// Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素
System.out.println("Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素 ");
System.out.println(Collections.max(arrayList, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof String && o2 instanceof String) {
String str_o1 = (String) o1;
String str_o2 = (String) o2;
int a = str_o1.length();
int b = str_o2.length();
int result = a == b ? str_o1.compareTo(str_o2) : a - b;
return result;
} else {
return 0;
}
}
}));
// (3)Object min(Collection):根据元素的自然顺序,返回给定集合中的最小元素
System.out.println("Object min(Collection):根据元素的自然顺序,返回给定集合中的最小元素");
System.out.println(Collections.min(arrayList));
// Object max(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最大元素
System.out.println("Object min(Collection, Comparator):根据Compartor指定的顺序,返回给定集合中的最小元素 ");
System.out.println(Collections.min(arrayList, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof String && o2 instanceof String) {
String str_o1 = (String) o1;
String str_o2 = (String) o2;
int a = str_o1.length();
int b = str_o2.length();
int result = a == b ? str_o1.compareTo(str_o2) : a - b;
return result;
} else {
return 0;
}
}
}));
// int frequency(Collection, Object):返回指定集合中指定元素的出现次数
System.out.println("int frequency(Collection, Object):返回指定集合中指定元素的出现次数 ");
System.out.println(Collections.frequency(arrayList, "Rose"));
// void copy(List dest, List src):将src中的内容复制到dest中
// 拷贝要注意 ,拷贝后的集合dest的元素个数要>=被拷贝集合arrayList
// 一般情况在初始化dest指定大小和arrayList相同
//ArrayList dest = new ArrayList(); // java.lang.IndexOutOfBoundsException
ArrayList dest = new ArrayList();
for (int i = 0; i < arrayList.size(); i++) {
dest.add(i);
}
dest.add("Copy");
dest.add("Paste");
Collections.copy(dest, arrayList);
System.out.println("dest集合元素:");
System.out.println(dest);
ArrayList arrayList1 = new ArrayList(10); // 指的是容量(达到后下次扩容成当前的1.5倍)
System.out.println("arrayList1.size(): " + arrayList1.size());
//boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值
System.out.println("boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值 ");
Collections.replaceAll(dest, "周润发", "金喜善"); // 如果有周润发就替换成金喜善
System.out.println(dest);
}
package com.HomeWork;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* @author wty
* @date 2022/10/10 16:06
*/
public class HomeWork01 {
@Test
public void HomeWork() {
ArrayList arrayList = new ArrayList();
arrayList.add(new News("新闻一:新冠确诊病例超过千万,数以万计印度教徒赶赴恒河"));
arrayList.add(new News("新闻二:男子突然想起2个月前钓的鱼还在网兜"));
System.out.println("----倒序遍历----");
Collections.reverse(arrayList);
for (Object o : arrayList) {
// 先实例化对象
News news = (News) o;
if (news.getTitle().length() > 15) {
System.out.println(news.getTitle().substring(0, 15) + "…………");
} else {
System.out.println(news.getTitle());
}
}
}
@Test
public void HomeWork01_Teacher() {
ArrayList arrayList = new ArrayList();
arrayList.add(new News("新闻一:新冠确诊病例超过千万,数以万计印度教徒赶赴恒河"));
arrayList.add(new News("新闻二:男子突然想起2个月前钓的鱼还在网兜"));
System.out.println("----倒序遍历----");
for (int i = arrayList.size() - 1; i >= 0; i--) {
News news = (News) arrayList.get(i);
System.out.println(substrTitle(news.getTitle()));
}
}
public String substrTitle(String title) {
if (null == title || "".equals(title)) {
return "";
}
if (title.length() > 15) {
return title.substring(0, 15) + "…………";
} else {
return title;
}
}
}
class News {
private String title;
private String text;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@Override
public String toString() {
return "News{" +
"title='" + title + '\'' +
'}';
}
public News(String title) {
this.title = title;
}
}
package com.HomeWork;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author wty
* @date 2022/10/10 16:38
*/
public class HomeWork02 {
@Test
public void getHomeWork02() {
List list = new ArrayList();
Car car1 = new Car("宝马", 400000);
Car car2 = new Car("宾利", 5000000);
Car car3 = new Car("劳斯莱斯", 60000000);
Car car4 = new Car("法拉利", 70000000);
list.add(car1);
list.add(car2);
System.out.println(list);
list.remove(car1);
System.out.println(list);
System.out.println(list.contains(car2));
System.out.println(list.size());
System.out.println(list.isEmpty());
list.clear();
System.out.println(list);
List list2 = new ArrayList();
list2.add(car1);
list2.add(car2);
list2.add(car3);
list2.add(car4);
list.addAll(list2);
System.out.println("----list.addAll(list2)----");
System.out.println(list);
System.out.println(list2.containsAll(list));
list2.removeAll(list);
System.out.println(list2);
System.out.println("list增强for循环");
for (Object o : list) {
System.out.println(o);
}
System.out.println("list迭代器");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
}
}
class Car {
private String name;
private double price;
public Car(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
package com.HomeWork;
import org.junit.Test;
import java.util.*;
/**
* @author wty
* @date 2022/10/10 16:52
*/
public class HomeWork03 {
@Test
public void getHomeWork03() {
Map map = new HashMap();
map.put("1", new Worker("jack", 650));
map.put("2", new Worker("tom", 1200));
map.put("3", new Worker("smith", 2900));
System.out.println("正常情况");
Set set = map.keySet();
for (Object o : set) {
Worker worker = (Worker) map.get(o);
System.out.println(worker);
}
// jack更改为2600元
System.out.println("----更改工资和加薪后----");
map.put("1", new Worker("jack", 2600));
System.out.println(map);
// 为所有员工加薪100元
Set set1 = map.entrySet();
Iterator iterator = set1.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
Map.Entry entry = (Map.Entry) next;
Worker worker = (Worker) entry.getValue();
// 加薪
worker.setSal(worker.getSal() + 100);
//System.out.println(worker.getSal() + 100);
System.out.println(worker);
}
System.out.println("----遍历工资----");
// 把工资遍历出来
Collection values = map.values();
for (Object value : values) {
Worker worker = (Worker) value;
System.out.println(worker.getSal());
}
}
}
class Worker {
private String name;
private double sal;
public Worker(String name, double sal) {
this.name = name;
this.sal = sal;
}
@Override
public String toString() {
return name + "————" + sal + "元";
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
}
试分析HashSet和TreeSet分别是如何实现去重的
(1)HashSet的去重机制:hashCode() + equals(),底层先通过存入对象,进行运算得到一个hash值,通过hash值得到对应的索引,如果发现table索引所在的位置,没有数据,就直接存放,如果有数据,就进行equals比较[遍历比较],如果比较后不相同就加入,否则就不加入。
(2)TreeSet的去重机制:如果你传入了一个Comparator匿名对象,就使用实现的compare去重,如果方法返回0,就认为是相同的元素/数据,就不添加,如果你没有传入一个Comparator匿名对象,则以你添加的对象实现的Comparator接口的compareTo去重。
package com.HomeWork;
import org.junit.Test;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* @author wty
* @date 2022/10/10 17:47
*/
public class HomeWork05 {
@Test
public void getHomeWorker05() {
TreeSet treeSet = new TreeSet();
treeSet.add(new Person()); // java.lang.ClassCastException 报错
// 错误原因:treeSet在add时候会执行
/**
* final int compare(Object var1, Object var2) {
* return this.comparator == null ? ((Comparable)var1).compareTo(var2) : this.comparator.compare(var1, var2);
* }
*
* 会把加入的元素var1 转换成(Comparable) 对象,所以Person必须实现Comparable接口才行
*/
}
}
class Person implements Comparable { // 实现之后再添加就不会报错了
/**
*TreeSet的去重机制:如果你传入了一个Comparator匿名对象,就使用实现的compare去重,如果方法返回 0,就认为是相同的元素/数据,就不添加,如果你没有传入一个Comparator匿名对象,则以你添加的对象实现的Comparator接口的compareTo去重。
* final int compare(Object var1, Object var2) {
* return this.comparator == null ? ((Comparable)var1).compareTo(var2) : this.comparator.compare(var1, var2);
* }
* @param o
* @return
*/
@Override
public int compareTo(Object o) {
return 0;
}
}
Vector和ArrayList比较
底层结构 版本 线程安全(同步)效率 扩容倍数
ArrayList 可变数组 1.2 线程不安全,效率高 无参第一次扩容至10,从第二次开始按照1.5倍扩容
Vector 可变数组 1.0 线程安全,效率低 无参第一次扩容至10,从第二次开始按照2倍扩容
名称 | 底层结构 | 版本 | 线程安全(同步) | 效率 | 扩容倍数 |
---|---|---|---|---|---|
ArrayList | 可变数组 | 1.2 | 线程不安全 | 高 | 无参第一次扩容至10,从第二次开始按照1.5倍扩容 |
Vector | 可变数组 | 1.0 | 线程安全 | 低 | 无参第一次扩容至10,从第二次开始按照2倍扩容 |