0基础学java-day14-(集合)

一、集合

前面我们保存多个数据使用的是数组,那么数组有不足的地方,我们分析一下

1.数组

2 集合 

  • 数据类型也可以不一样 

3.集合的框架体系 

  • Java 的集合类很多,主要分为两大类,如图 :[背下来]

 

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;/*** @author 林然* @version 1.0*/
public class Collection_ {public static void main(String[] args) {//1. 集合主要是两组(单列集合 , 双列集合)//2. Collection 接口有两个重要的子接口 List 和Set , 他们的实现子类都是单列集合//3. Map 接口的实现子类 是双列集合,存放的 K-V//4. 把老师梳理的两张图记住ArrayList arrayList =new ArrayList();arrayList.add("jack");arrayList.add("tom");HashMap hashMap =new HashMap();hashMap.put("No1","北京");}
}

4.Collection 接口和常用方法

4.1Collection 接口实现类的特点

  • Collection 接口常用方法,以实现子类 ArrayList 来演示 

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.List;/*** @author 林然* @version 1.0*/
public class CollectionMethod {@SuppressWarnings("all")public static void main(String[] args) {List list =new ArrayList();// add:添加单个元素list.add("jack");list.add(10);//这里相当于自动装箱了,添加的实际是对象list.add(true);System.out.println("list="+list);// remove:删除指定元素
//list.remove(0);//删除第一个元素list.remove(true);//指定删除某个元素System.out.println("list=" + list);// contains:查找元素是否存在System.out.println(list.contains("jack"));//T// size:获取元素个数System.out.println(list.size());//2// isEmpty:判断是否为空System.out.println(list.isEmpty());//F// clear:清空list.clear();System.out.println("list=" + list);// addAll:添加多个元素ArrayList list2=new ArrayList();list2.add("加油");list2.add("java大神");list.addAll(list2);System.out.println("list=" + list);// containsAll:查找多个元素是否都存在System.out.println(list.containsAll(list2));//T// removeAll:删除多个元素list.add("聊斋");list.removeAll(list2);System.out.println("list=" + list);//[聊斋]}
}

4.2 Collection 接口遍历元素方式 1-使用 Iterator(迭代器)

 

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/*** @author 林然* @version 1.0*/
@SuppressWarnings({"all"})
public class CollectionIterator {public static void main(String[] args) {Collection col = new ArrayList();col.add(new Book1("三国演义", "罗贯中", 10.1));col.add(new Book1("小李飞刀", "古龙", 5.1));col.add(new Book1("红楼梦", "曹雪芹", 34.6));//现在老师希望能够遍历 col 集合//1. 先得到 col 对应的 迭代器Iterator iterator =col.iterator();//2. 使用 while 循环遍历// while (iterator.hasNext()) {//判断是否还有数据// //返回下一个元素,类型是 Object// Object obj = iterator.next();// System.out.println("obj=" + obj);// }//教大家一个快捷键,快速生成 while => itit//显示所有的快捷键的的快捷键 ctrl + jwhile (iterator.hasNext()) {Object next =  iterator.next();System.out.println(next);}//3. 当退出 while 循环后 , 这时 iterator 迭代器,指向最后的元素// iterator.next();//NoSuchElementException//4. 如果希望再次遍历,需要重置我们的迭代器iterator = col.iterator();System.out.println("===第二次遍历===");while (iterator.hasNext()) {Object obj = iterator.next();System.out.println("obj=" + obj);}}
}
@SuppressWarnings({"all"})
class Book1 {private String name;private String author;private double price;public Book1(String name, String author, double price) {this.name = name;this.author = author;this.price = price;}@Overridepublic String toString() {return "Book1{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +'}';}
}

4.3 Collection 接口遍历对象方式 2-for 循环增强

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.Collection;/*** @author 林然* @version 1.0*/
public class CollectionFor {@SuppressWarnings("all")public static void main(String[] args) {Collection col = new ArrayList();col.add(new Book1("三国演义", "罗贯中", 10.1));col.add(new Book1("小李飞刀", "古龙", 5.1));col.add(new Book1("红楼梦", "曹雪芹", 34.6));//使用增强for循环for(Object k:col){System.out.println("book="+k);}}}

 4.4 课堂练习

package com.hspedu.collection_;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class CollectionExercise {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();list.add(new Dog("小黑", 3));list.add(new Dog("大黄", 100));list.add(new Dog("大壮", 8));//先使用for增强for (Object dog : list) {System.out.println("dog=" + dog);}//使用迭代器System.out.println("===使用迭代器来遍历===");Iterator iterator = list.iterator();while (iterator.hasNext()) {Object dog =  iterator.next();System.out.println("dog=" + dog);}}
}
/*** 创建  3个 Dog {name, age}  对象,放入到 ArrayList 中,赋给 List 引用* 用迭代器和增强for循环两种方式来遍历* 重写Dog 的toString方法, 输出name和age*/
class Dog {private String name;private int age;public Dog(String name, int age) {this.name = name;this.age = 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;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", age=" + age +'}';}
}

 二、List 

1.List 接口和常用方法 

1.1  List 接口基本介绍

package com.hspedu.list_;import java.util.ArrayList;
import java.util.List;/*** @author 林然* @version 1.0*/
public class List_ {@SuppressWarnings("all")public static void main(String[] args) {//1. List 集合类中元素有序(即添加顺序和取出顺序一致)、且可重复 [案例]List list = new ArrayList();list.add("jack");list.add("tom");list.add("mary");list.add("lsl");list.add("tom");System.out.println("list=" + list);
//2. List 集合中的每个元素都有其对应的顺序索引,即支持索引
// 索引是从 0 开始的System.out.println(list.get(3));//lsl
//3}
}

 1.2 List 接口的常用方法

package com.hspedu.list_;import java.util.ArrayList;
import java.util.List;/*** @author 林然* @version 1.0*/
public class ListMethod {@SuppressWarnings("all")public static void main(String[] args) {List list =new ArrayList();list.add("张三丰");list.add("贾宝玉");
// void add(int index, Object ele):在 index 位置插入 ele 元素//在 index = 1 的位置插入一个对象list.add(1, "林然");System.out.println("list=" + list);// boolean addAll(int index, Collection eles):从 index 位置开始将 eles 中的所有元素添加进来List list2 = new ArrayList();list2.add("jack");list2.add("tom");list.addAll(1, list2);System.out.println("list=" + list);// Object get(int index):获取指定 index 位置的元素// int indexOf(Object obj):返回 obj 在集合中首次出现的位置System.out.println(list.indexOf("tom"));//2// int lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置list.add("林然");System.out.println("list=" + list);System.out.println(list.lastIndexOf("林然"));// Object remove(int index):移除指定 index 位置的元素,并返回此元素list.remove(0);System.out.println("list=" + list);// Object set(int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换. list.set(1, "玛丽");System.out.println("list=" + list);// List subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合
// 注意返回的子集合 fromIndex <= subList < toIndexList returnlist = list.subList(0, 2);System.out.println("returnlist=" + returnlist);}
}

 1.3 List 接口课堂练习

package com.hspedu.list_;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class ListExercise {@SuppressWarnings({"all"})public static void main(String[] args) {/*添加10个以上的元素(比如String "hello" ),在2号位插入一个元素"韩顺平教育",获得第5个元素,删除第6个元素,修改第7个元素,在使用迭代器遍历集合,要求:使用List的实现类ArrayList完成。*/List list = new ArrayList();for (int i = 0; i < 12; i++) {list.add("hello" + i);}System.out.println("list=" + list);//在2号位插入一个元素"韩顺平教育"list.add(1, "韩顺平教育");System.out.println("list=" + list);//获得第5个元素System.out.println("第五个元素=" + list.get(4));//删除第6个元素list.remove(5);System.out.println("list=" + list);//修改第7个元素list.set(6, "三国演义");System.out.println("list=" + list);//在使用迭代器遍历集合Iterator iterator = list.iterator();while (iterator.hasNext()) {Object obj =  iterator.next();System.out.println("obj=" + obj);}}
}

 1.4 List 的三种遍历方式 [ArrayList, LinkedList,Vector]

package com.hspedu.list_;import java.util.*;public class ListFor {@SuppressWarnings({"all"})public static void main(String[] args) {//List 接口的实现子类 Vector LinkedList//List list = new ArrayList();//List list = new Vector();List list = new LinkedList();list.add("jack");list.add("tom");list.add("鱼香肉丝");list.add("北京烤鸭子");//遍历//1. 迭代器Iterator iterator = list.iterator();while (iterator.hasNext()) {Object obj =  iterator.next();System.out.println(obj);}System.out.println("=====增强for=====");//2. 增强forfor (Object o : list) {System.out.println("o=" + o);}System.out.println("=====普通for====");//3. 使用普通forfor (int i = 0; i < list.size(); i++) {System.out.println("对象=" + list.get(i));}}
}

 1.5 实现类的课堂练习 2

package com.hspedu.list_;import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;@SuppressWarnings({"all"})
public class ListExercise02 {public static void main(String[] args) {//List list = new ArrayList();List list = new LinkedList();//List list = new Vector();list.add(new Book("红楼梦", "曹雪芹", 100));list.add(new Book("西游记", "吴承恩", 10));list.add(new Book("水浒传", "施耐庵", 19));list.add(new Book("三国", "罗贯中", 80));//list.add(new Book("西游记", "吴承恩", 10));//如何对集合进行排序//遍历for (Object o : list) {System.out.println(o);}//冒泡排序sort(list);System.out.println("==排序后==");for (Object o : list) {System.out.println(o);}}//静态方法//价格要求是从小到大public static void sort(List list) {int listSize = list.size();for (int i = 0; i < listSize - 1; i++) {for (int j = 0; j < listSize - 1 - i; j++) {//取出对象BookBook book1 = (Book) list.get(j);Book book2 = (Book) list.get(j + 1);if (book1.getPrice() > book2.getPrice()) {//交换list.set(j, book2);list.set(j + 1, book1);}}}}
}

package com.hspedu.list_;public class Book {private String name;private String author;private double price;public Book(String name, String author, double price) {this.name = name;this.author = author;this.price = 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;}@Overridepublic String toString() {return "名称:" + name + "\t\t价格:" + price + "\t\t作者:" + author;}
}

2.ArrayList 底层结构和源码分析

2.1 ArrayList 的注意事项

2.2 ArrayList 的底层操作机制源码分析(重点,难点.) 

 3.Vector 底层结构和源码剖析

3.1 Vector 的基本介绍

3.2 Vector ArrayList 的比较 

4.LinkedList 底层结构 

4.1 LinkedList 的全面说明

4.2 LinkedList 的底层操作机制 

【这里其实就是涉及数据结构的知识点】

package com.hspedu.list_;public class LinkedList01 {public static void main(String[] args) {//模拟一个简单的双向链表Node jack = new Node("jack");Node tom = new Node("tom");Node hsp = new Node("老韩");//连接三个结点,形成双向链表//jack -> tom -> hspjack.next = tom;tom.next = hsp;//hsp -> tom -> jackhsp.pre = tom;tom.pre = jack;Node first = jack;//让first引用指向jack,就是双向链表的头结点Node last = hsp; //让last引用指向hsp,就是双向链表的尾结点//演示,从头到尾进行遍历System.out.println("===从头到尾进行遍历===");while (true) {if(first == null) {break;}//输出first 信息System.out.println(first);first = first.next;}//演示,从尾到头的遍历System.out.println("====从尾到头的遍历====");while (true) {if(last == null) {break;}//输出last 信息System.out.println(last);last = last.pre;}//演示链表的添加对象/数据,是多么的方便//要求,是在 tom --------- 老韩直接,插入一个对象 smith//1. 先创建一个 Node 结点,name 就是 smithNode smith = new Node("smith");//下面就把 smith 加入到双向链表了smith.next = hsp;smith.pre = tom;hsp.pre = smith;tom.next = smith;//让first 再次指向jackfirst = jack;//让first引用指向jack,就是双向链表的头结点System.out.println("===从头到尾进行遍历===");while (true) {if(first == null) {break;}//输出first 信息System.out.println(first);first = first.next;}last = hsp; //让last 重新指向最后一个结点//演示,从尾到头的遍历System.out.println("====从尾到头的遍历====");while (true) {if(last == null) {break;}//输出last 信息System.out.println(last);last = last.pre;}}
}//定义一个Node 类,Node 对象 表示双向链表的一个结点
class Node {public Object item; //真正存放数据public Node next; //指向后一个结点public Node pre; //指向前一个结点public Node(Object name) {this.item = name;}public String toString() {return "Node name=" + item;}
}

 4.3 LinkedList 的增删改查案例

package com.hspedu.list_;import java.util.Iterator;
import java.util.LinkedList;/*** @author 韩顺平* @version 1.0*/
@SuppressWarnings({"all"})
public class LinkedListCRUD {public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add(1);linkedList.add(2);linkedList.add(3);System.out.println("linkedList=" + linkedList);//演示一个删除结点的linkedList.remove(); // 这里默认删除的是第一个结点//linkedList.remove(2);System.out.println("linkedList=" + linkedList);//修改某个结点对象linkedList.set(1, 999);System.out.println("linkedList=" + linkedList);//得到某个结点对象//get(1) 是得到双向链表的第二个对象Object o = linkedList.get(1);System.out.println(o);//999//因为LinkedList 是 实现了List接口, 遍历方式System.out.println("===LinkeList遍历迭代器====");Iterator iterator = linkedList.iterator();while (iterator.hasNext()) {Object next =  iterator.next();System.out.println("next=" + next);}System.out.println("===LinkeList遍历增强for====");for (Object o1 : linkedList) {System.out.println("o1=" + o1);}System.out.println("===LinkeList遍历普通for====");for (int i = 0; i < linkedList.size(); i++) {System.out.println(linkedList.get(i));}//老韩源码阅读./* 1. LinkedList linkedList = new LinkedList();public LinkedList() {}2. 这时 linkeList 的属性 first = null  last = null3. 执行 添加public boolean add(E e) {linkLast(e);return true;}4.将新的结点,加入到双向链表的最后void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;}*//*老韩读源码 linkedList.remove(); // 这里默认删除的是第一个结点1. 执行 removeFirstpublic E remove() {return removeFirst();}2. 执行public E removeFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return unlinkFirst(f);}3. 执行 unlinkFirst, 将 f 指向的双向链表的第一个结点拿掉private E unlinkFirst(Node<E> f) {// assert f == first && f != null;final E element = f.item;final Node<E> next = f.next;f.item = null;f.next = null; // help GCfirst = next;if (next == null)last = null;elsenext.prev = null;size--;modCount++;return element;}*/}
}

4.4 ArrayList LinkedList 比较

三、Set 

1.Set 接口和常用方法 

1.1 Set 接口基本介绍

1.2 Set 接口的常用方法 

List 接口一样 , Set 接口也是 Collection 的子接口,因此,常用方法和 Collection 接口一样

1.3 Set 接口的遍历方式

1.4 Set 接口的常用方法举例 

package com.hspedu.set_;import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;@SuppressWarnings({"all"})
public class SetMethod {public static void main(String[] args) {//老韩解读//1. 以Set 接口的实现类 HashSet 来讲解Set 接口的方法//2. set 接口的实现类的对象(Set接口对象), 不能存放重复的元素, 可以添加一个null//3. set 接口对象存放数据是无序(即添加的顺序和取出的顺序不一致)//4. 注意:取出的顺序的顺序虽然不是添加的顺序,但是他的固定【就是每次得到的顺序的固定的】.Set set = new HashSet();set.add("john");set.add("lucy");set.add("john");//重复,由于重复,只会有一个set.add("jack");set.add("hsp");set.add("mary");set.add(null);//set.add(null);//再次添加null,由于重复,只会有一个for(int i = 0; i <10;i ++) {System.out.println("set=" + set);}//遍历//方式1: 使用迭代器System.out.println("=====使用迭代器====");Iterator iterator = set.iterator();while (iterator.hasNext()) {Object obj =  iterator.next();System.out.println("obj=" + obj);}set.remove(null);//方式2: 增强forSystem.out.println("=====增强for====");for (Object o : set) {System.out.println("o=" + o);}//set 接口对象,不能通过索引来获取}
}

2.HashSet

2.1 HashSet 的全面说明

package com.hspedu.set_;import java.util.HashSet;
import java.util.Set;@SuppressWarnings({"all"})
public class HashSet_ {public static void main(String[] args) {//老韩解读//1. 构造器走的源码/*public HashSet() {map = new HashMap<>();}2. HashSet 可以存放null ,但是只能有一个null,即元素不能重复*/Set hashSet = new HashSet();hashSet.add(null);hashSet.add(null);System.out.println("hashSet=" + hashSet);}
}

 2.2 HashSet 案例说明

package com.hspedu.set_;import java.util.HashSet;@SuppressWarnings({"all"})
public class HashSet01 {public static void main(String[] args) {HashSet set = new HashSet();//说明//1. 在执行add方法后,会返回一个boolean值//2. 如果添加成功,返回 true, 否则返回false//3. 可以通过 remove 指定删除哪个对象System.out.println(set.add("john"));//TSystem.out.println(set.add("lucy"));//TSystem.out.println(set.add("john"));//FSystem.out.println(set.add("jack"));//TSystem.out.println(set.add("Rose"));//Tset.remove("john");System.out.println("set=" + set);//3个//set  = new HashSet();System.out.println("set=" + set);//0//4 Hashset 不能添加相同的元素/数据?set.add("lucy");//添加成功set.add("lucy");//加入不了set.add(new Dog("tom"));//OKset.add(new Dog("tom"));//OkSystem.out.println("set=" + set);//在加深一下. 非常经典的面试题.//看源码,做分析, 先给小伙伴留一个坑,以后讲完源码,你就了然//去看他的源码,即 add 到底发生了什么?=> 底层机制.set.add(new String("hsp"));//okset.add(new String("hsp"));//加入不了.System.out.println("set=" + set);}
}
class Dog { //定义了Dog类private String name;public Dog(String name) {this.name = name;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +'}';}
}

 2.3 HashSet 底层机制说明

package com.hspedu.set_;@SuppressWarnings({"all"})
public class HashSetStructure {public static void main(String[] args) {//模拟一个HashSet的底层 (HashMap 的底层结构)//1. 创建一个数组,数组的类型是 Node[]//2. 有些人,直接把 Node[] 数组称为 表Node[] table = new Node[16];//3. 创建结点Node john = new Node("john", null);table[2] = john;Node jack = new Node("jack", null);john.next = jack;// 将jack 结点挂载到johnNode rose = new Node("Rose", null);jack.next = rose;// 将rose 结点挂载到jackNode lucy = new Node("lucy", null);table[3] = lucy; // 把lucy 放到 table表的索引为3的位置.System.out.println("table=" + table);}
}
class Node { //结点, 存储数据, 可以指向下一个结点,从而形成链表Object item; //存放数据Node next; // 指向下一个结点public Node(Object item, Node next) {this.item = item;this.next = next;}
}

 【在这里我们可以看到他用得是equals,由于字符串改写了,其比较的是内容,之前的一个案例就在这里被解释了】

【如果table没到64,但是链表超过8,将会对table进行扩容】

 【下面的源码更加说明了上面的结论】

package com.hspedu.set_;import java.util.HashSet;/*** @author 韩顺平* @version 1.0*/
@SuppressWarnings({"all"})
public class HashSetSource {public static void main(String[] args) {HashSet hashSet = new HashSet();hashSet.add("java");//到此位置,第1次add分析完毕.hashSet.add("php");//到此位置,第2次add分析完毕hashSet.add("java");System.out.println("set=" + hashSet);/*对HashSet 的源码解读1. 执行 HashSet()public HashSet() {map = new HashMap<>();}2. 执行 add()public boolean add(E e) {//e = "java"return map.put(e, PRESENT)==null;//(static) PRESENT = new Object();}3.执行 put() , 该方法会执行 hash(key) 得到key对应的hash值 算法h = key.hashCode()) ^ (h >>> 16)public V put(K key, V value) {//key = "java" value = PRESENT 共享return putVal(hash(key), key, value, false, true);}4.执行 putValfinal V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i; //定义了辅助变量//table 就是 HashMap 的一个数组,类型是 Node[]//if 语句表示如果当前table 是null, 或者 大小=0//就是第一次扩容,到16个空间.if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;//(1)根据key,得到hash 去计算该key应该存放到table表的哪个索引位置//并把这个位置的对象,赋给 p//(2)判断p 是否为null//(2.1) 如果p 为null, 表示还没有存放元素, 就创建一个Node (key="java",value=PRESENT)//(2.2) 就放在该位置 tab[i] = newNode(hash, key, value, null)if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {//一个开发技巧提示: 在需要局部变量(辅助变量)时候,在创建Node<K,V> e; K k; ////如果当前索引位置对应的链表的第一个元素和准备添加的key的hash值一样//并且满足 下面两个条件之一://(1) 准备加入的key 和 p 指向的Node 结点的 key 是同一个对象//(2)  p 指向的Node 结点的 key 的equals() 和准备加入的key比较后相同//就不能加入if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;//再判断 p 是不是一颗红黑树,//如果是一颗红黑树,就调用 putTreeVal , 来进行添加else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {//如果table对应索引位置,已经是一个链表, 就使用for循环比较//(1) 依次和该链表的每一个元素比较后,都不相同, 则加入到该链表的最后//    注意在把元素添加到链表后,立即判断 该链表是否已经达到8个结点//    , 就调用 treeifyBin() 对当前这个链表进行树化(转成红黑树)//    注意,在转成红黑树时,要进行判断, 判断条件//    if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY(64))//            resize();//    如果上面条件成立,先table扩容.//    只有上面条件不成立时,才进行转成红黑树//(2) 依次和该链表的每一个元素比较过程中,如果有相同情况,就直接breakfor (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD(8) - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;//size 就是我们每加入一个结点Node(k,v,h,next), size++if (++size > threshold)resize();//扩容afterNodeInsertion(evict);return null;}*/}
}

2.4 HashSet 课堂练习 1

package com.hspedu.set_;import java.util.HashSet;
import java.util.Objects;/*** @author 林然* @version 1.0*/
public class HashSetExercise {@SuppressWarnings("all")public static void main(String[] args) {/**定义一个 Employee 类,该类包含:private 成员属性 name,age 要求:创建 3 个 Employee 对象放入 HashSet 中当 name 和 age 的值相同时,认为是相同员工, 不能添加到 HashSet 集合中*/HashSet hashSet = new HashSet();hashSet.add(new Employee("milan", 18));//okhashSet.add(new Employee("smith", 28));//okhashSet.add(new Employee("milan", 18));//加入不成功System.out.println("hashSet=" + hashSet);}
}
//创建 Employee
class Employee{private String name;private int age;public Employee(String name, int age) {this.name = name;this.age = 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;}@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Employee employee = (Employee) o;return age == employee.age &&Objects.equals(name, employee.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}

 2.5 HashSet 课后练习 2

3.LinkedHashSet 

3.1 LinkedHashSet 的全面说明

package com.hspedu.set_;import java.util.LinkedHashSet;
import java.util.Set;@SuppressWarnings({"all"})
public class LinkedHashSetSource {public static void main(String[] args) {//分析一下LinkedHashSet的底层机制Set set = new LinkedHashSet();set.add(new String("AA"));set.add(456);set.add(456);set.add(new Customer("刘", 1001));set.add(123);set.add("HSP");System.out.println("set=" + set);//1. LinkedHashSet 加入顺序和取出元素/数据的顺序一致//2. LinkedHashSet 底层维护的是一个LinkedHashMap(是HashMap的子类)//3. LinkedHashSet 底层结构 (数组table+双向链表)//4. 添加第一次时,直接将 数组table 扩容到 16 ,存放的结点类型是 LinkedHashMap$Entry//5. 数组是 HashMap$Node[] 存放的元素/数据是 LinkedHashMap$Entry类型/*//继承关系是在内部类完成.static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after;Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}}*/}
}
class Customer {private String name;private int no;public Customer(String name, int no) {this.name = name;this.no = no;}
}

3.2 LinkedHashSet 课后练习题

package com.hspedu.set_;import java.util.LinkedHashSet;
import java.util.Objects;@SuppressWarnings({"all"})
public class LinkedHashSetExercise {public static void main(String[] args) {LinkedHashSet linkedHashSet = new LinkedHashSet();linkedHashSet.add(new Car("奥拓", 1000));//OKlinkedHashSet.add(new Car("奥迪", 300000));//OKlinkedHashSet.add(new Car("法拉利", 10000000));//OKlinkedHashSet.add(new Car("奥迪", 300000));//加入不了linkedHashSet.add(new Car("保时捷", 70000000));//OKlinkedHashSet.add(new Car("奥迪", 300000));//加入不了System.out.println("linkedHashSet=" + linkedHashSet);}
}/*** Car 类(属性:name,price),  如果 name 和 price 一样,* 则认为是相同元素,就不能添加。 5min*/class Car {private String name;private double price;public Car(String name, double price) {this.name = name;this.price = price;}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;}@Overridepublic String toString() {return "\nCar{" +"name='" + name + '\'' +", price=" + price +'}';}//重写equals 方法 和 hashCode//当 name 和 price 相同时, 就返回相同的 hashCode 值, equals返回t@Overridepublic 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);}@Overridepublic int hashCode() {return Objects.hash(name, price);}
}

 四、Map

1.Map 接口和常用方法 

1.1 Map 接口实现类的特点 [很实用]

package com.hspedu.map_;import java.util.HashMap;
import java.util.Map;/*** @author 林然* @version 1.0*/
public class Map_ {@SuppressWarnings("all")public static void main(String[] args) {//老韩解读 Map 接口实现类的特点, 使用实现类 HashMap//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 总能找到对应的 valueMap map =new HashMap();map.put("no1","林然");//k-vmap.put("no2","林然2");//k-vmap.put("no1","张三丰");//k-v 当有相同的 k , 就等价于替换.map.put("no3","张三丰");//k-vmap.put(null,null);//k-vmap.put(null,"abc");//k-v 当有相同的 k , 就等价于替换map.put("no4",null);//k-vmap.put(1, "赵敏");//k-vmap.put(new Object(), "金毛狮王");//k-v// 通过 get 方法,传入 key ,会返回对应的 valueSystem.out.println(map.get("no2"));//林然System.out.println(map);}
}

package com.hspedu.map_;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;@SuppressWarnings({"all"})
public class MapSource_ {public static void main(String[] args) {Map map = new HashMap();map.put("no1", "韩顺平");//k-vmap.put("no2", "张无忌");//k-vmap.put(new Car(), new Person());//k-v//老韩解读//1. k-v 最后是 HashMap$Node node = newNode(hash, key, value, null)//2. k-v 为了方便程序员的遍历,还会 创建 EntrySet 集合 ,该集合存放的元素的类型 Entry, 而一个Entry//   对象就有k,v EntrySet<Entry<K,V>> 即: transient Set<Map.Entry<K,V>> entrySet;//3. entrySet 中, 定义的类型是 Map.Entry ,但是实际上存放的还是 HashMap$Node//   这时因为 static class Node<K,V> implements Map.Entry<K,V>//4. 当把 HashMap$Node 对象 存放到 entrySet 就方便我们的遍历, 因为 Map.Entry 提供了重要方法//   K getKey(); V getValue();Set set = map.entrySet();System.out.println(set.getClass());// HashMap$EntrySetfor (Object obj : set) {//System.out.println(obj.getClass()); //HashMap$Node//为了从 HashMap$Node 取出k-v//1. 先做一个向下转型Map.Entry entry = (Map.Entry) obj;System.out.println(entry.getKey() + "-" + entry.getValue() );}Set set1 = map.keySet();System.out.println(set1.getClass());Collection values = map.values();System.out.println(values.getClass());}
}class Car {}class Person{}

1.2 常用方法

 

package com.hspedu.map_;import java.util.HashMap;
import java.util.Map;/*** @author 林然* @version 1.0*/public class MapMethod {public static void main(String[] args) {//演示 map 接口常用方法Map map = new HashMap();map.put("邓超", new Book("", 100));//OKmap.put("邓超", "孙俪");//替换-> 一会分析源码map.put("王宝强", "马蓉");//OKmap.put("宋喆", "马蓉");//OKmap.put("刘令博", null);//OKmap.put(null, "刘亦菲");//OKmap.put("鹿晗", "关晓彤");//OKmap.put("hsp", "hsp 的老婆");System.out.println("map=" + map);
// remove:根据键删除映射关系map.remove(null);System.out.println("map=" + map);
// get:根据键获取值Object val = map.get("鹿晗");System.out.println("val=" + val);
// size:获取元素个数System.out.println("k-v=" + map.size());
// isEmpty:判断个数是否为 0System.out.println(map.isEmpty());//F
// clear:清除 k-v
//map.clear();System.out.println("map=" + map);
// containsKey:查找键是否存在System.out.println("结果=" + map.containsKey("hsp"));//T}
}class Book {private String name;private int num;public Book(String name, int num) {this.name = name;this.num = num;}
}

 1.3 Map 接口遍历方法

package com.hspedu.map_;import java.util.*;/*** @author 林然* @version 1.0*/
@SuppressWarnings("all")
public class MapFor {public static void main(String[] args) {Map map = new HashMap();map.put("邓超", "孙俪");map.put("王宝强", "马蓉");map.put("宋喆", "马蓉");map.put("刘令博", null);map.put(null, "刘亦菲");map.put("鹿晗", "关晓彤");//第一组: 先取出 所有的 Key , 通过 Key 取出对应的 ValueSet keyset = map.keySet();//(1) 增强 forSystem.out.println("-----第一种方式-------");for (Object key : keyset) {System.out.println(key + "-" + map.get(key));}//(2) 迭代器System.out.println("----第二种方式--------");Iterator iterator = keyset.iterator();while (iterator.hasNext()) {Object key = iterator.next();System.out.println(key + "-" + map.get(key));}//第二组: 把所有的 values 取出Collection values = map.values();//这里可以使用所有的 Collections 使用的遍历方法//(1) 增强 forSystem.out.println("---取出所有的 value 增强 for----");for (Object value : values) {System.out.println(value);}
//(2) 迭代器System.out.println("---取出所有的 value 迭代器----");Iterator iterator2 = values.iterator();while (iterator2.hasNext()){Object value = iterator2.next();System.out.println(value);}//第三组: 通过 EntrySet 来获取 k-vSet entrySet = map.entrySet();// EntrySet<Map.Entry<K,V>>
//(1) 增强 forSystem.out.println("----使用 EntrySet 的 for 增强(第 3 种)----");for (Object entry : entrySet) {
//将 entry 转成 Map.EntryMap.Entry m = (Map.Entry) entry;System.out.println(m.getKey() + "-" + m.getValue());}
//(2) 迭代器System.out.println("----使用 EntrySet 的 迭代器(第 4 种)----");Iterator iterator3 = entrySet.iterator();while (iterator3.hasNext()) {Object entry = iterator3.next();
//System.out.println(next.getClass());//HashMap$Node -实现-> Map.Entry (getKey,getValue)
//向下转型 Map.EntryMap.Entry m = (Map.Entry) entry;System.out.println(m.getKey() + "-" + m.getValue());}}
}

 1.4 Map 接口课堂练习

package com.hspedu.map_;import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;@SuppressWarnings({"all"})
public class MapExercise {public static void main(String[] args) {//完成代码Map hashMap = new HashMap();//添加对象hashMap.put(1, new Emp("jack", 300000, 1));hashMap.put(2, new Emp("tom", 21000, 2));hashMap.put(3, new Emp("milan", 12000, 3));//遍历2种方式//并遍历显示工资>18000的员工(遍历方式最少两种)//1. 使用keySet  -> 增强forSet keySet = hashMap.keySet();System.out.println("====第一种遍历方式====");for (Object key : keySet) {//先获取valueEmp emp = (Emp) hashMap.get(key);if(emp.getSal() >18000) {System.out.println(emp);}}//2. 使用EntrySet -> 迭代器//   体现比较难的知识点//   慢慢品,越品越有味道.Set entrySet = hashMap.entrySet();System.out.println("======迭代器======");Iterator iterator = entrySet.iterator();while (iterator.hasNext()) {Map.Entry entry =  (Map.Entry)iterator.next();//通过entry 取得key 和 valueEmp emp = (Emp) entry.getValue();if(emp.getSal() > 18000) {System.out.println(emp);}}}
}
/*** 使用HashMap添加3个员工对象,要求* 键:员工id* 值:员工对象** 并遍历显示工资>18000的员工(遍历方式最少两种)* 员工类:姓名、工资、员工id*/
class Emp {private String name;private double sal;private int id;public Emp(String name, double sal, int id) {this.name = name;this.sal = sal;this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSal() {return sal;}public void setSal(double sal) {this.sal = sal;}public int getId() {return id;}public void setId(int id) {this.id = id;}@Overridepublic String toString() {return "Emp{" +"name='" + name + '\'' +", sal=" + sal +", id=" + id +'}';}
}

 2.Map 接口实现类-HashMap

2.1 HashMap 小结 

2.2 HashMap 底层机制及源码剖析 

package com.hspedu.map_;import java.util.HashMap;@SuppressWarnings({"all"})
public class HashMapSource1 {public static void main(String[] args) {HashMap map = new HashMap();map.put("java", 10);//okmap.put("php", 10);//okmap.put("java", 20);//替换valueSystem.out.println("map=" + map);///*老韩解读HashMap的源码+图解1. 执行构造器 new HashMap()初始化加载因子 loadfactor = 0.75HashMap$Node[] table = null2. 执行put 调用 hash方法,计算 key的 hash值 (h = key.hashCode()) ^ (h >>> 16)public V put(K key, V value) {//K = "java" value = 10return putVal(hash(key), key, value, false, true);}3. 执行 putValfinal V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;//辅助变量//如果底层的table 数组为null, 或者 length =0 , 就扩容到16if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;//取出hash值对应的table的索引位置的Node, 如果为null, 就直接把加入的k-v//, 创建成一个 Node ,加入该位置即可if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;//辅助变量// 如果table的索引位置的key的hash相同和新的key的hash值相同,// 并 满足(table现有的结点的key和准备添加的key是同一个对象  || equals返回真)// 就认为不能加入新的k-vif (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)//如果当前的table的已有的Node 是红黑树,就按照红黑树的方式处理e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {//如果找到的结点,后面是链表,就循环比较for (int binCount = 0; ; ++binCount) {//死循环if ((e = p.next) == null) {//如果整个链表,没有和他相同,就加到该链表的最后p.next = newNode(hash, key, value, null);//加入后,判断当前链表的个数,是否已经到8个,到8个,后//就调用 treeifyBin 方法进行红黑树的转换if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash && //如果在循环比较过程中,发现有相同,就break,就只是替换value((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value; //替换,key对应valueafterNodeAccess(e);return oldValue;}}++modCount;//每增加一个Node ,就size++if (++size > threshold[12-24-48])//如size > 临界值,就扩容resize();afterNodeInsertion(evict);return null;}5. 关于树化(转成红黑树)//如果table 为null ,或者大小还没有到 64,暂时不树化,而是进行扩容.//否则才会真正的树化 -> 剪枝final void treeifyBin(Node<K,V>[] tab, int hash) {int n, index; Node<K,V> e;if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)resize();}*/}
}

3.Map 接口实现类-Hashtable

3.1 HashTable 的基本介绍

 扩容【2倍+1】

package com.hspedu.map_;import java.util.Hashtable;@SuppressWarnings({"all"})
public class HashTableExercise {public static void main(String[] args) {Hashtable table = new Hashtable();//oktable.put("john", 100); //ok//table.put(null, 100); //异常 NullPointerException//table.put("john", null);//异常 NullPointerExceptiontable.put("lucy", 100);//oktable.put("lic", 100);//oktable.put("lic", 88);//替换table.put("hello1", 1);table.put("hello2", 1);table.put("hello3", 1);table.put("hello4", 1);table.put("hello5", 1);table.put("hello6", 1);System.out.println(table);//简单说明一下Hashtable的底层//1. 底层有数组 Hashtable$Entry[] 初始化大小为 11//2. 临界值 threshold 8 = 11 * 0.75//3. 扩容: 按照自己的扩容机制来进行即可.//4. 执行 方法 addEntry(hash, key, value, index); 添加K-V 封装到Entry//5. 当 if (count >= threshold) 满足时,就进行扩容//5. 按照 int newCapacity = (oldCapacity << 1) + 1; 的大小扩容.}
}

3.2 Hashtable HashMap 对比

4.Map 接口实现类-Properties 

4.1基本介绍

4.2 基本使用 

package com.hspedu.map_;import java.util.Properties;/*** @author Linran* @version 1.0*/
@SuppressWarnings({"all"})
public class Properties_ {public static void main(String[] args) {//老韩解读//1. Properties 继承  Hashtable//2. 可以通过 k-v 存放数据,当然key 和 value 不能为 null//增加Properties properties = new Properties();//properties.put(null, "abc");//抛出 空指针异常//properties.put("abc", null); //抛出 空指针异常properties.put("john", 100);//k-vproperties.put("lucy", 100);properties.put("lic", 100);properties.put("lic", 88);//如果有相同的key , value被替换System.out.println("properties=" + properties);//通过k 获取对应值System.out.println(properties.get("lic"));//88//删除properties.remove("lic");System.out.println("properties=" + properties);//修改properties.put("john", "约翰");System.out.println("properties=" + properties);}
}

 五、总结-开发中如何选择集合实现类(记住)

 5.1TreeSet源码解读

package com.hspedu.set_;import java.util.Comparator;
import java.util.TreeSet;/*** @author 林然* @version 1.0*/
@SuppressWarnings({"all"})
public class TreeSet_ {public static void main(String[] args) {//1. 当我们使用无参构造器,创建TreeSet时,仍然是无序的//2. 老师希望添加的元素,按照字符串大小来排序//3. 使用TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)//   并指定排序规则//4. 简单看看源码/*1. 构造器把传入的比较器对象,赋给了 TreeSet的底层的 TreeMap的属性this.comparatorpublic TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}2. 在 调用 treeSet.add("tom"), 在底层会执行到if (cpr != null) {//cpr 就是我们的匿名内部类(对象)do {parent = t;//动态绑定到我们的匿名内部类(对象)comparecmp = cpr.compare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;else //如果相等,即返回0,这个Key就没有加入return t.setValue(value);} while (t != null);}*///        TreeSet treeSet = new TreeSet();TreeSet treeSet = new TreeSet(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {//下面 调用String的 compareTo方法进行字符串大小比较//如果老韩要求加入的元素,按照长度大小排序//return ((String) o2).compareTo((String) o1);return ((String) o1).length() - ((String) o2).length();}});//添加数据.treeSet.add("jack");treeSet.add("tom");//3treeSet.add("sp");treeSet.add("a");treeSet.add("abc");//3,并不会加入System.out.println("treeSet=" + treeSet);}
}

 5.2 TreeMap源码解读

package com.hspedu.map_;import java.util.Comparator;
import java.util.TreeMap;/*** @author 林然* @version 1.0*/
@SuppressWarnings({"all"})
public class TreeMap_ {public static void main(String[] args) {//使用默认的构造器,创建TreeMap, 是无序的(也没有排序)/*老韩要求:按照传入的 k(String) 的大小进行排序*/
//        TreeMap treeMap = new TreeMap();TreeMap treeMap = new TreeMap(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {//按照传入的 k(String) 的大小进行排序//按照K(String) 的长度大小排序//return ((String) o2).compareTo((String) o1);return ((String) o2).length() - ((String) o1).length();}});treeMap.put("jack", "杰克");treeMap.put("tom", "汤姆");treeMap.put("kristina", "克瑞斯提诺");treeMap.put("smith", "斯密斯");treeMap.put("hsp", "韩顺平");//加入不了,会把汤姆修改成韩顺平System.out.println("treemap=" + treeMap);/*老韩解读源码:1. 构造器. 把传入的实现了 Comparator接口的匿名内部类(对象),传给给TreeMap的comparatorpublic TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}2. 调用put方法2.1 第一次添加, 把k-v 封装到 Entry对象,放入rootEntry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}2.2 以后添加Comparator<? super K> cpr = comparator;if (cpr != null) {do { //遍历所有的key , 给当前key找到适当位置parent = t;cmp = cpr.compare(key, t.key);//动态绑定到我们的匿名内部类的compareif (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;else  //如果遍历过程中,发现准备添加Key 和当前已有的Key 相等,就不添加return t.setValue(value);} while (t != null);}*/}
}

 六、Collections 工具类

1 Collections 工具类介绍 

2 排序操作:(均为 static 方法) 

package com.hspedu.collections_;import java.util.*;/*** @author 林然* @version 1.0*/
@SuppressWarnings("all")
public class Collections_ {public static void main(String[] args) {//创建 ArrayList 集合,用于测试.List list = new ArrayList();list.add("tom");list.add("smith");list.add("king");list.add("milan");list.add("tom");// reverse(List):反转 List 中元素的顺序Collections.reverse(list);System.out.println(list);// shuffle(List):对 List 集合元素进行随机排序// for (int i = 0; i < 5; i++) {// Collections.shuffle(list);// System.out.println("list=" + list);//sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序Collections.sort(list);System.out.println("自然排序后");System.out.println("list=" + list);//按照首字母进行排序// sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
//我们希望按照 字符串的长度大小排序Collections.sort(list, new Comparator() {@Overridepublic int compare(Object o1, Object o2) {
//可以加入校验代码.return ((String) o2).length() - ((String) o1).length();}});System.out.println("字符串长度大小排序=" + list);// swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
//比如Collections.swap(list, 0, 1);System.out.println("交换后的情况");System.out.println("list=" + list);//Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素System.out.println("自然顺序最大元素=" + Collections.max(list));//Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
//比如,我们要返回长度最大的元素Object maxObject = Collections.max(list, new Comparator() {@Overridepublic int compare(Object o1, Object o2) {return ((String)o1).length() - ((String)o2).length();}});System.out.println("长度最大的元素=" + maxObject);//Object min(Collection)//Object min(Collection,Comparator)//上面的两个方法,参考 max 即可//int frequency(Collection,Object):返回指定集合中指定元素的出现次数System.out.println("tom 出现的次数=" + Collections.frequency(list, "tom"));//void copy(List dest,List src):将 src 中的内容复制到 dest 中ArrayList dest = new ArrayList();
//为了完成一个完整拷贝,我们需要先给 dest 赋值,大小和 list.size()一样for(int i = 0; i < list.size(); i++) {dest.add("");}
//拷贝Collections.copy(dest, list);System.out.println("dest=" + dest);//boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
//如果 list 中,有 tom 就替换成 汤姆Collections.replaceAll(list, "tom", "汤姆");System.out.println("list 替换后=" + list);}
}

七、本章作业

1.作业一 

package com.hspedu.homework;import java.util.ArrayList;
import java.util.Collections;/*** @author 林然* @version 1.0*/
@SuppressWarnings("all")
public class homework1 {public static void main(String[] args) {News1 new1=new News1("新冠确诊病例超千万,数百万印度教信徒赴恒河\"圣浴\"引民众担忧");News1 new2=new News1("男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生");ArrayList arrayList =new ArrayList();arrayList.add(new1);arrayList.add(new2);Collections.reverse(arrayList);for (Object k:arrayList) {News1 k1 = (News1)k;if(k1.getTitle().length()>=15)System.out.println(k1.getTitle().substring(0, 15) + "...");elseSystem.out.println(k1.getTitle());}}
}
class News1{private String title;private String content;public News1(String title) {this.title = title;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overridepublic String toString() {return "News{" +"title='" + title + '\'' +", content='" + content + '\'' +'}';}
}

 2.作业二

package com.hspedu.homework;import java.util.ArrayList;
import java.util.Iterator;@SuppressWarnings({"all"})
public class Homework02 {public static void main(String[] args) {ArrayList arrayList = new ArrayList();Car car = new Car("宝马", 400000);Car car2 = new Car("宾利",5000000);//1.add:添加单个元素arrayList.add(car);arrayList.add(car2);System.out.println(arrayList);//* 2.remove:删除指定元素arrayList.remove(car);System.out.println(arrayList);//* 3.contains:查找元素是否存在System.out.println(arrayList.contains(car));//F//* 4.size:获取元素个数System.out.println(arrayList.size());//1//* 5.isEmpty:判断是否为空System.out.println(arrayList.isEmpty());//F//* 6.clear:清空//System.out.println(arrayList.clear(););//* 7.addAll:添加多个元素System.out.println(arrayList);arrayList.addAll(arrayList);//2个宾利System.out.println(arrayList);//* 8.containsAll:查找多个元素是否都存在arrayList.containsAll(arrayList);//T//* 9.removeAll:删除多个元素//arrayList.removeAll(arrayList); //相当于清空//* 使用增强for和 迭代器来遍历所有的car , 需要重写 Car 的toString方法for (Object o : arrayList) {System.out.println(o);//}System.out.println("===迭代器===");Iterator iterator = arrayList.iterator();while (iterator.hasNext()) {Object next =  iterator.next();System.out.println(next);}}
}
/*** 使用ArrayList 完成对 对象 Car {name, price} 的各种操作* 1.add:添加单个元素* 2.remove:删除指定元素* 3.contains:查找元素是否存在* 4.size:获取元素个数* 5.isEmpty:判断是否为空* 6.clear:清空* 7.addAll:添加多个元素* 8.containsAll:查找多个元素是否都存在* 9.removeAll:删除多个元素* 使用增强for和 迭代器来遍历所有的car , 需要重写 Car 的toString方法*/
class Car {private String name;private double price;public Car(String name, double price) {this.name = name;this.price = price;}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;}@Overridepublic String toString() {return "Car{" +"name='" + name + '\'' +", price=" + price +'}';}
}

 3.作业三

package com.hspedu.homework;import java.util.*;/*** @author 林然* @version 1.0*/
public class homework3 {@SuppressWarnings("all")public static void main(String[] args) {Map m = new HashMap();m.put("jack",650);m.put("tom",1200);m.put("smith",2900);m.replace("jack",2600);Set keys =m.keySet();//更新工资for(Object k :keys){   int salary=(int)(m.get(k));m.replace(k,salary+100);}//遍历集合中的员工//遍历 EntrySetSet entrySet = m.entrySet();//迭代器Iterator iterator = entrySet.iterator();while (iterator.hasNext()) {Map.Entry entry =  (Map.Entry)iterator.next();System.out.println(entry.getKey() + "-" + entry.getValue());}System.out.println("====遍历所有的工资====");Collection values = m.values();for (Object value : values) {System.out.println("工资=" + value);}}
}

 4.作业四

5.作业五 

//package com.hspedu.homework;
//
//import java.util.TreeSet;
////@SuppressWarnings({"all"})
//public class Homework05 {
//    public static void main(String[] args) {
//        TreeSet treeSet = new TreeSet();
//        //分析源码
//        //add 方法,因为 TreeSet() 构造器没有传入Comparator接口的匿名内部类
//        //所以在底层 Comparable<? super K> k = (Comparable<? super K>) key;
//        //即 把 Perosn转成 Comparable类型
//        treeSet.add(new Person());//ClassCastException.
//        treeSet.add(new Person());//ClassCastException.
//        treeSet.add(new Person());//ClassCastException.
//        treeSet.add(new Person());//ClassCastException.
//        treeSet.add(new Person());//ClassCastException.
//
//        System.out.println(treeSet);
//
//    }
//}
//
//class Person implements Comparable{
//
//    @Override
//    public int compareTo(Object o) {
//        return 0;
//    }
//}

 6.作业六

【只要id和name不一样,那么我们认为他们不是同一个对象】

【remove中是利用1001和CC来计算哈希值,也就是他没办法找到p1所在的位置【1001+AA】】

package com.hspedu.homework;import java.util.HashSet;
import java.util.Objects;@SuppressWarnings({"all"})
public class Homework06 {public static void main(String[] args) {HashSet set = new HashSet();//okPerson p1 = new Person(1001,"AA");//okPerson p2 = new Person(1002,"BB");//okset.add(p1);//okset.add(p2);//okp1.name = "CC";set.remove(p1);System.out.println(set);//2set.add(new Person(1001,"CC"));System.out.println(set);//3set.add(new Person(1001,"AA"));System.out.println(set);//4}
}class Person {public String name;public int id;public Person(int id, String name) {this.name = name;this.id = id;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return id == person.id &&Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, id);}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", id=" + id +'}';}
}

7.作业七

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/213108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式之GoF23介绍

深入探讨设计模式&#xff1a;构建可维护、可扩展的软件架构 一、设计模式的背景1.1 什么是设计模式1.2 设计模式的历史 二、设计模式的分类2.1 创建型模式2.2 结构型模式2.3 行为型模式 三、七大设计原则四、设计模式关系结论 :rocket: :rocket: :rocket: 在软件开发领域&…

算法:爬楼梯(迭代和动态规划)

迭代 时间复杂度 O(n) 空间复杂度 O(1) /*** param {number} n* return {number}*/ var climbStairs function(n) {let l 0, r 0 , sum 1for(let i1; i<n; i){l rr sumsum l r}return sum }; 动态规划 时间复杂度 O(n) 空间复杂度 O(n) /*** param {number} n* r…

【密码学基础】Diffie-Hellman密钥交换协议

DH介绍 Diffie-Hellman密钥协议算法是一种确保共享密钥安全穿越不安全网络的方法。 这个机制的巧妙在于需要安全通信的双方可以用这个方法确定对称密钥&#xff0c;然后可以用这个密钥进行加密和解密。 但是注意&#xff0c;这个密钥交换协议 只能用于密钥的交换&#xff0c;而…

Java面试题(每天10题)-------连载(45)

Dubbo篇 1、Dubbo的服务调用流程 2、Dubbo支持那种协议&#xff0c;每种协议的应用场景&#xff0c;优缺点&#xff1f; dubbo&#xff1a; 单一长连接和 NIO 异步通讯&#xff0c;适合大并发小数据量的服务调用&#xff0c;以及消费者远大于提供者。传输协议 TCP&#xff0c;…

Proteus仿真--射击小游戏仿真设计

本文介绍基于proteus射击小游戏仿真设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 K1-K4为4个按键&#xff0c;用于上移、下移、确认等&#xff0c;模拟单机游戏 仿真运行视频 Proteus仿真--射击小游戏仿真设计 附完整Proteus仿真资料代码资料 …

ArcGIS界面显示分辨率调整

因为电脑显示分辨率的问题呢&#xff0c;ArcGIS的界面显示会字体显示不合适&#xff0c;出现模糊情况&#xff0c;这时候只需要做个简单的操作设置一下便可以解决&#xff01; 1、右键ArcMap的快捷启动方式。 2、对应选择兼容性——>更高DPI设置——>勾选替代DPI缩放行为…

体系化学习运筹学基础算法的实践和总结

文章目录 引言目标设计目标实践文章汇总经验总结一则预告 引言 眨眼间已经12月了&#xff0c;眼看着2023年马上要过完了。 女朋友最近总说&#xff0c;工作以后感觉时间过的好快。事实上&#xff0c;我也是这么认为的。年纪越大&#xff0c;越会担心35岁危机的降临。所以&…

Xubuntu16.04系统中使用EDIMAX EW-7822UAC无线网卡开启5G自发AP

目录 1.关于 EDIMAX EW-7822UAC2.驱动安装3.查看无线网卡信息3.通过create_ap配置5G自发AP 1.关于 EDIMAX EW-7822UAC 官网介绍 https://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/global/wireless_adapters_ac1200_dual-band/ew-7822uac/ 详细参数…

Python开发运维:Python项目发布到K8S集群

目录 一、实验 1.Python项目发布到K8S集群 一、实验 1.Python项目发布到K8S集群 &#xff08;1&#xff09;获取应用程序代码 #把hello-python.tar.gz压缩包上传到k8s控制节点master1的root下&#xff0c;手动解压 tar zxvf hello-python.tar.gz &#xff08;2&#xff0…

【Linux】进程周边001之进程概念

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.基本概念 2.描述进程-PCB…

LeetCode5.最长回文子串

昨天和之前打比赛的队友聊天&#xff0c;他说他面百度面到这道算法题&#xff0c;然后他用暴力法解的&#xff0c;面试官让他优化他没优化出来&#xff0c;这道题我之前没写过&#xff0c;我就想看看我能不能用效率高一点的方法把它做出来&#xff0c;我一开始就在想用递归或者…

设计CPU功能的数字电路

实验目的(1)熟悉Multisim 电路仿真软件的操作界面和功能; (2)掌握逻辑电路综合设计,并采用仿真软件进行仿真。 实验内容1.试设计一个简易CPU功能的数字电路,实验至少要求采用4个74HC/HCT194作为4个存储单元(可以预先对存储单元存储数据),74HC283作为计算单元。请实现…

多维时序 | MATLAB实现RIME-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现RIME-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现RIME-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现RIME-CNN-…

idea本地调试hadoop 遇到的几个问题

1.DEA对MapReduce的toString调用报错&#xff1a;Method threw ‘java.lang.IllegalStateException‘ exception. Cannot evaluate org.apache.hadoop.mapreduc 解决方法&#xff1a;关闭 IDEA 中的启用“ tostring() ”对象视图 2.代码和hdfs路径都对的情况下&#xff0c;程序…

架构设计系列之基础:初探软件架构设计

11 月开始突发奇想&#xff0c;想把自己在公司内部做的技术培训、平时的技术总结等等的内容分享出来&#xff0c;于是就开通了一个 Wechat 订阅号&#xff08;灸哥漫谈&#xff09;&#xff0c;开始同步发送内容。 今天&#xff08;12 月 10 日&#xff09;也同步在 CSDN 上开通…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《面向微电网群的云储能经济-低碳-可靠多目标优化配置方法》

这篇文章的标题涵盖了以下关键信息&#xff1a; 面向微电网群&#xff1a;研究的重点是微电网群&#xff0c;这可能指的是多个微电网系统的集合&#xff0c;而不仅仅是一个单独的微电网。微电网是指由分布式能源资源、储能系统和智能控制组成的小型电力系统&#xff0c;通常能够…

实现加盐加密方法以及java nio中基于MappedByteBuffer操作大文件

自己实现 传统MD5可通过彩虹表暴力破解&#xff0c; 加盐加密算法是一种常用的密码保护方法&#xff0c;它将一个随机字符串&#xff08;盐&#xff09;添加到原始密码中&#xff0c;然后再进行加密处理。 1. 每次调用方法产生一个唯一盐值&#xff08;UUID &#xff09;密码…

UDS诊断 10服务

文章目录 简介诊断会话切换请求和响应1、请求2、子功能3、肯定响应4、否定响应5、特殊的NRC 为什么划分不同会话报文示例UDS中常用 NRC参考 简介 10服务&#xff0c;即 Diagnostic Session Control&#xff08;诊断会话控制&#xff09;服务用于启用服务器中的不同诊断会话&am…

(四) python门面模式

文章目录 4.1 结构型设计模式4.1.1 简介4.1.2 常见的几种结构型设计模式 4.2 理解门面设计模式4.2.1 门面设计模式概述4.2.2 门面设计模式的作用 4.3 UML类图4.3.1 门面4.3.2 系统4.3.3 客户端 4.4 门面模式的代码实现4.4.1 场景&#xff1a;4.4.2 python实现 4.5 原理&#xf…

渲染(iOS渲染过程解析)

渲染 渲染原理 一个硬核硬件科普视频 CPU和GPU CPU&#xff08;Central Processing Unit&#xff09;&#xff1a;现代计算机整个系统的运算核心、控制核心&#xff0c;适合串行计算。GPU&#xff08;Graphics Processing Unit&#xff09;&#xff1a;可进行绘图运算工作的…