aQueue_QueueDemo01
package com.se.aQueue;
import java.util.LinkedList;
import java.util.Queue;
/**
* Queue: 队列,也是Collection接口的子接口
* 用来描述一种,先进先出(FIFO)的数据存储结构
* 可以理解为是一种特殊的线性表,只能从一头进入,另一头出来
* 对应的方法
* -boolean offer(E e): 从队列的尾部进入
* -E poll(): 从队列的头部出来
* -E peek(): 获取队列的头部元素,不删除
*/
public class QueueDemo01 {
public static void main(String[] args) {
//创建一个名字队列
Queue<String> name = new LinkedList<>();
//调用offer方法,入队
name.offer("micheal");
name.offer("张三");
name.offer("李四");
//查看队列样子
System.out.println(name);
//查看队列的头部对象
String head = name.peek();
System.out.println(head);
//让头部元素出队
while (name.peek() != null) {
//如果想要移除头部元素,最好先查看是否有头部元素,如果有才移除
String head1 = name.poll();
System.out.println(head1);
System.out.println(name);
}
}
}
aQueue_QueueDemo02
package com.se.aQueue;
import java.util.Deque;
import java.util.LinkedList;
/**
* 双端队列:即从队列两头都可以入队和出队
* Deque接口,实现了双端队列的存储结构,是Queue的子接口
* 对应的实现类,还是LinkedList();
* 提供的方法:
* offerFirst
* offerLast
* pollFirst
* pollLast
*/
public class QueueDemo02 {
public static void main(String[] args) {
//创建一个双端队列
Deque<String> names = new LinkedList<>();
//添加第一个元素
names.offer("小张");
//第二个元素从头部进入
names.offerFirst("小芯");
//第三个元素从尾部进入
names.offerLast("小心");
System.out.println(names);
//移除元素
//移除头部元素
String head = names.poll();
System.out.println(head);
//移除尾部元素
String tail = names.pollLast();
System.out.println(tail);
System.out.println(names);
}
}
aQueue_QueueDemo03
package com.se.aQueue;
import java.util.Deque;
import java.util.LinkedList;
/**
* 使用DeQueue模拟栈的存储结构:
* 栈: FILO 先进后出
*/
public class QueueDemo03 {
public static void main(String[] args) {
Deque<String> stack = new LinkedList<>();
//出口进入 push 将元素推入
stack.push("小张");//在栈的底部
stack.push("小芯");//在栈的倒数第二层
stack.push("小心");//在栈的倒数第三层
stack.push("小心?");//在栈的倒数第四层
System.out.println(stack);
//出栈
while (stack.size() > 0) {
String el = stack.pop();
System.out.println(el);
}
}
}
bSet_Person
package com.se.bSet;
/**
* 先不重写equals和hashCode,全都继承自Object类
*/
public class Person {
private String name;
private int age;
public Person(){}
public Person(String name, int age){
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean equals(Object obj){
if(obj == null){
return false;
}
if(!(obj instanceof Person)){
return false;
}
if (this == obj){
return true;
}
Person p = (Person) obj;
return name.equals(p.getName()) && age == p.getAge();
}
/*
重写hasCode方法的原则:尽量让所有的成员变量都参与运算
*/
public int hashCode(){
return name.hashCode() + age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
bSet_PersonTest
package com.se.bSet;
import java.util.HashSet;
import java.util.Set;
/**
* 重写和不重写equals和hashCode方法的案例演示
* 针对与集合框架,尤其是Set而言
*/
public class PersonTest {
public static void main(String[] args) {
Set<Person> ps = new HashSet<Person>();
//存入集合
ps.add(new Person("michael", 18));
ps.add(new Person("john", 19));
ps.add(new Person("tom", 18));
ps.add(new Person("michael", 18));
System.out.println(ps);
//需求:查看有没有一个叫michael,18岁的人
Person p1 = new Person("michael", 18);
Person p2 = new Person("michael", 18);
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
/*
调用contains方法,判定是否包含p1
1. 通过输出语句发现返回的是false
先调用hashCode方法,如果p1和p2的hashCode值不同,就认为不存在
如果值相同,还是调用equals方法,如果返回true,就认为存在,否则不存在
2. 结论:
在自定义类的时候,如果这个类要存入到Set集合中,需要重写HasCode和equals方法
基于上述需求,我们自定义的类就应该重写这两个方法,因为我们也不知道未来如何使用
*/
boolean b = ps.contains(p1);
System.out.println("是否包含:"+b);
}
}
bSet_PersonTest02
package com.se.bSet;
import java.util.HashSet;
import java.util.Set;
/**
* 案例演示: 将元素存储到集合后,修改元素的hash值
* 1. 修改了元素的属性,会有如下结果:
* 重复的元素就可以添加到集合中
* 被修改属性的旧元素无法修改
* 2. 综上所述:
* 当将对象存入集合后,就不要修改对象的属性
*/
public class PersonTest02 {
public static void main(String[] args) {
Set<Person> set = new HashSet<>();
Person p1 = new Person("小明", 18);
Person p2 = new Person("小张", 19);
Person p3 = new Person("小王", 18);
set.add(p1);
set.add(p2);
set.add(p3);
//因为我们重新写了equasl方法和hashCode方法,添加失败
Person p4 = new Person("小王", 18);
set.add(p4);
System.out.println(set);
//修改p3的age为20
p3.setAge(20);
//添加与p3相同的对象
Person p5 = new Person("小王", 20);
set.add(p5);
System.out.println(set);
//删除p3
set.remove(p3);
//从结果上看,有一个和p3相同的对象被删除
System.out.println(set);
}
}
bSet_SetDemo01
package com.se.bSet;
import java.util.HashSet;
import java.util.Set;
/**
* Set接口: 是Collection的子接口
* 设计初衷:
* 用来存储不重复的元素,元素的顺序是无序的(取出的顺序和存入的顺序无关)
* 一旦存入,在结构里面的顺序就固定了,和存入顺序无关
* set接口里的方法,都是Collection的方法,
* - HashSet: 实现了Set接口的最经典的子类型
* 底层的存储方式使用的是Hash算法(哈希表)
*/
public class SetDemo01 {
public static void main(String[] args) {
//创建一个Set接口的对象
Set<String> names = new HashSet<>();
//存入
names.add("michael");
names.add("lucy");
names.add("john");
names.add("tom");
System.out.println(names);
//打印四个元素的hash值
System.out.println("michael".hashCode() % 16);
System.out.println("lucy".hashCode() % 16);
System.out.println("john".hashCode() % 16);
System.out.println("tom".hashCode() % 16);
/*
去重原理:
先计算要添加的元素的hash值,然后缺点哈希表中该值的位置上是否存在元素
如果不存在,则添加成功,如果存在,就需要调用equals方法进行比较,
如果equals方法返回true,则添加失败,
如果返回false,则添加成功
注意: 每个hash值对应的位置都维护了一个单向链表,
可以进入储存hash值相同,equals不同的元素
*/
//添加元素 michael
names.add("michael"); //因为数据结构中已经存在michael,所以添加失败
System.out.println(names);
System.out.println(names.size());
}
}
bSet_SetDemo02
package com.se.bSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* HashSet的遍历
*/
public class SetDemo02 {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(10);
set.add(20);
set.add(30);
set.add(40);
set.add(50);
System.out.println(set);
//1. set是无序的,不能使用fori循环遍历
//2. 可以使用增强for循环遍历
for (Integer i : set) {
System.out.print(i);
}
System.out.println();
//3. 可以使用迭代器遍历
Iterator<Integer> it = set.iterator();
while (it.hasNext()) {
Integer ele = it.next();
System.out.print(ele);
}
}
}
bSet_SetDemo03
package com.se.bSet;
/**
* 1. LinkedHashSet是HashSet 的子类
* 2. LinkedHashSet集合根据元素的 hashCode 值来决定元素的存储位置,
* 但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
* 3. LinkedHashSet 性能插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能
* 4. LinkedHashSet不允许集合元素重复
*/
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
public class SetDemo03 {
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<>();
set.add("a");
set.add("b");
set.add("c");
set.add("bob");
System.out.println(set);
//迭代器遍历
Iterator<String> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
bSet_SetDemo04
package com.se.bSet;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
/**
* TreeSet的应用:
* 1. TreeSet是SortedSet接口的实现类,
* 2. TreeSet集合的元素是有序的,即内部维护一个二叉树算法的排序方式
* 3. TreeSet集合的元素不能有重复的元素
* 4. TreeSet元素是默认按照升序排列的,如果想要改变顺序,需要自定义一个比较器,传入构造器中
*
* tips: LinkedHashSet,使用链表维护箱集合中插入元素是的顺序
*/
public class SetDemo04 {
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("a");
set.add("h");
set.add("b");
set.add("f");
set.add("d");
set.add("bob");
set.add("bab");
System.out.println(set);
Comparator<Integer> c1 = (o1, o2) -> o2 - o1;
Set<Integer> nums = new TreeSet<>(c1);
nums.add(10);
nums.add(1);
nums.add(20);
nums.add(2);
System.out.println(nums);
}
}
cSort_SortDemo01
package com.se.cSort;
/**
* 1. 自定义的类,如果想要排序,不管是在数组中,还是在集合中。
* 要求元素必须是Comparable的子类型,因为底层需要调用Comparable接口的compareTo方法。
* 所以,我们自定义的类,如果想要排序,那么就必须实现Comparable接口
* 以及重写compareTo方法
* 2. 在上述的基础上,如果想要重新指定排序方式,不应该修改compareTo方法里的逻辑
* 而是应该使用Comparator接口,来定义一个新的比较规则。调用集合或者数组的
* 相关充足方法,可以传入一个比较器的这样的方法,进行新的排序。
*/
public class SortDemo01 {
}
cSort_SortDemo02
package com.se.cSort;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 集合工具类: Collections 数组工具类: Arrays
* 1. 集合工具类和数组工具类一样,都提供了很多常用的方法,来操作集合对象
* -void sort(List<E> list): 对集合进行升序排序
* -void sort(List<E> list, Comparator<E> c): 使用比较器,重新定义规则
*/
public class SortDemo02 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add((int) (Math.random() * 100));
}
System.out.println(list);
/*
利用工具类里的方法对集合进行排序
*/
Collections.sort(list);
System.out.println(list);
//由于集合工具类的sort方法是按照升序进行排序的,
//想要降序,所以需要使用比较器,重新定义规则
Comparator<Integer> c1 = (o1, o2) -> o2 - o1;
Collections.sort(list, c1);
System.out.println(list);
}
}
dCollections_CollectionsDemo01
package com.se.dCollections;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* 集合工具类的其他方法演示:
*/
public class CollectionsDemo01 {
public static void main(String[] args) {
List<String> names = new LinkedList<>();
names.add("michael");
names.add("peter");
names.add("mark");
names.add("john");
names.add("jane");
//打印集合: 顺序为添加时顺序
System.out.println(names);
//1. 调用集合工具类里反转方法,将集合元素颠倒过来
Collections.reverse(names);
System.out.println("翻转后结果"+names);
//2. 洗牌方法
Collections.shuffle(names);
System.out.println("洗牌后结果"+names);
//3. 将第二个和倒数第二个做一下交换
Collections.swap(names,1,names.size()-2);
System.out.println("交换后结果"+names);
//4. 调用max方法: 底层使用的是自然排序,找到最大值
String max = Collections.max(names);
System.out.println("最大值"+max);
//5. 调用min方法: 底层使用的是自然排序,找到最小值
String min = Collections.min(names);
System.out.println("最小值"+min);
//6. E Collections.max(List<E> list, Comparator c)
//7. E Collections.max(List<E> list, Comparator c)
names.add("michael");
names.add("michael");
names.add("michael");
System.out.println(names);
System.out.println(names.size());
//8. 调用工具类找出michael出现的次数
int count = Collections.frequency(names,"michael");
System.out.println("michael出现的次数为:"+count);
//9. 将集合里所有的michael替换成yor
Collections.replaceAll(names,"michael","yor");
System.out.println(names);
}
}
dCollections_CollectionsDemo02
package com.se.dCollections;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 数组与集合之间的转换
*/
public class CollectionsDemo02 {
public static void main(String[] args) {
/*
集合转数组 集合自有的方法
作用: 将集合转成Object[]
一旦想要使用数组,必须先转成Object[],需要强转
[T] toArray([T] a)
作用: 将集合转成数组
只需要传入一个元素类型的数组对象,就可以返回元素类型的数组
*/
List<String> names = new ArrayList<>();
names.add("michael");
names.add("peter");
names.add("mark");
Object[] arr1 = names.toArray();
//获取第二个元素的第二个字符
Object obj = arr1[1];
if (obj instanceof String) {
String str = (String) obj;
char ch = str.charAt(1);
System.out.println(ch);
}
//第二种方法
String[] arr = new String[0];
String[] arr2 = names.toArray(new String[0]);
System.out.println(Arrays.toString(arr2));
//判断第一个元素是不是以el结尾
if (arr2[0].endsWith("el")) {
System.out.println("以el结尾");
}
}
}
dCollections_CollectionsDemo03
package com.se.dCollections;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 数组转集合
* 1. 数组转成的集合对象,不能修改长度
* 2. 如果想要进行增删操作,可以将转成的集合里的元素放入一个新的集合里。对新集合进行操作。
*/
public class CollectionsDemo03 {
public static void main(String[] args) {
String[] names = new String[5];
names[0] = "michael";
names[1] = "tom";
names[2] = "lucy";
names[3] = "lily";
names[4] = "john";
List<String> list = Arrays.asList(names);
System.out.println(list);
//将集合里的第二个元素替换成张三
// list.set(1,"张三");
System.out.println(list);
// list.remove(1); //移除是修改集合长度
// list.add("张三"); //增加也是修改集合长度
//向集合中添加新元素,张三和李四,然后将张三与第一位交换位置
// String[] newnames = Arrays.copyOf(names, names.length + 2);
// newnames[5] = "张三";
// newnames[6] = "李四";
// List<String> list2 = Arrays.asList(newnames);
// System.out.println(list2);
// Collections.swap(list,0,5);
// System.out.println(list2);
List<String> other = new ArrayList<>(list);
other.add("张三");
other.add("李四");
int index = other.indexOf("张三");
Collections.swap(other,0,index);
System.out.println(other);
}
}
eMap_MapDemo01
package com.se.eMap;
import java.util.HashMap;
import java.util.Map;
/**
* 1. Map接口,是集合框架中的另一个父接口
* 2. Map存储的数据特点: 一对一的关系映射,称之为Key-Value-Pair
* 3. Map接口最常用的两个子类,是HashMap和TreeMap
* - HashMap:底层使用了Hash表和红黑树的数据结构(jdk1.8之前是hash表和单链表)
* - TreeMap:底层使用的是二叉树
* 4. Map的key是不能重复的,但是可以为null。 value可以重复
* 5. Map的key,可以理解为是value的索引,总能通过一个key找到一个具体的value
* 6. Map里的元素也是无序的(在结构中的存储顺序和存入顺序无关)
*/
public class MapDemo01 {
public static void main(String[] args) {
//创建一个Map集合(散列表)
Map<String,Integer> map = new HashMap<>();
//存储元素,调用put方法
map.put("张三", 100);
map.put("李四", 90);
map.put("王五", 80);
map.put("赵六", 70);
System.out.println(map);
//获取一个人的成绩 get(K k)
Integer score= map.get("张三");
System.out.println("张三的成绩"+score);
//存入,张三 60分
map.put("张三", 60); //tips: put方法,如果key相同,会覆盖原来的value
System.out.println(map);
//取出小八的成绩 get(K k): 如果key不存在,返回null
Integer s1 = map.get("小八");
System.out.println("小八的成绩"+s1);
//测试 key是否可以是null
map.put(null, 0);
System.out.println(map);
map.put(null, 10);
System.out.println(map);
}
}
eMap_MapDemo02
package com.se.eMap;
import java.util.HashMap;
/**
* Map的其他操作:
*/
public class MapDemo02 {
public static void main(String[] args) {
HashMap<String, String> course = new HashMap<>();
course.put("王", "语文");
course.put("李", "数学");
course.put("张", "化学");
course.put("赵", "生物");
System.out.println(course);
//1. boolean isEmpty() 判断是否为空
System.out.println("course集合是否为空" + course.isEmpty());
//2. boolean containsKey(Object key) 判断是否包含指定的键
System.out.println("是否包含张老师这个key:" + course.containsKey("张"));
//3. boolean containsValue(Object value) 判断是否包含指定的值
System.out.println("是否包含数学这个value:" + course.containsValue("数学"));
//4. remove(Object key) 删除指定键的键值对
course.remove("赵");
System.out.println(course);
//5. int size() 获取集合中键值对的个数
System.out.println("course集合中键值对的个数:" + course.size());
//6. clear 清空集合
course.clear();
System.out.println(course);
}
}
eMap_MapDemo03
package com.se.eMap;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Map集合的遍历
*/
public class MapDemo03 {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("michael", 100);
scores.put("lucy", 98);
scores.put("tom", 97);
scores.put("john", 99);
//第一种方式: 使用KeySet(): 返回所有的key的set集合形式
Set<String> keys = scores.keySet();
for (String key : keys) {
//通过key获取value
Integer value = scores.get(key);
System.out.println(key + "=" + value);
}
//第二种方式: 使用entrySet(): 返回所有的key-value的set集合形式
// Entry 是Map的内部类,Entry对象就是封装一对key-value
Set<Map.Entry<String, Integer>> es = scores.entrySet();
for (Map.Entry<String, Integer> entry : es) {
//每一个entry都是一个键值对
//System.out.println(entry);
//Entry类型提供了getKey()和getValue()方法
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + "=" + value);
}
//第三种方式: 使用values(): 返回所有的value的Collection集合形式
Collection<Integer> values = scores.values();
for (Integer value : values) {
System.out.println(value);
}
}
}
eMap_MapDemo04_LinkedHashMap
package com.se.eMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* LinkedHashMap:
* 1. 是HashMap的子类型
* 2. 使用链表维护了元素的插入顺序
*/
public class MapDemo04_LinkedHashMap {
public static void main(String[] args) {
Map<String, String> map = new LinkedHashMap<>();
map.put("张三", "北京");
map.put("李四", "上海");
map.put("王五", "北京");
map.put("赵六", "长春");
System.out.println(map);
}
}
eMap_MapDemo05_TreeMap
package com.se.eMap;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
/**
* TreeMap:
* 1. 使用二叉树对key进行排序,来维护整个集合的KV对的顺序
* 2. 默认升序,可以通过比较器自定义排序
*/
public class MapDemo05_TreeMap {
public static void main(String[] args) {
Comparator c1 = new Comparator<String>() {
public int compare(String o1, String o2) {
return -o1.compareTo(o2);
}
};
Map<String, Integer> map = new TreeMap<>(c1);
map.put("A", 100);
map.put("a", 90);
map.put("b", 80);
map.put("C", 90);
System.out.println(map);
}
}
eMap_MapDemo06_Properties
package com.se.eMap;
import java.util.Map;
import java.util.Properties;
/**
* Properties:
* 1. 是HashTable的子类型,比较常用,一般用于加载配置文件里的KEY和VALUE
* 2. 因为配置文件里都是字符串,因此Properties里的KEY和VALUE也都是String类型
* 3. 该对象的key和value都不能为null
*
*/
public class MapDemo06_Properties {
public static void main(String[] args) {
// 创建一个配置文件属性对象
Properties prop = new Properties();
// 添加几个key和value
prop.setProperty("url","jdbc:mysql://localhost:3306/mydb");
prop.setProperty("username","root");
prop.setProperty("password","root");
prop.setProperty("driver","com.mysql.jdbc.Driver");
System.out.println(prop);
System.out.println(prop.size());
//Properties的遍历
for (Map.Entry<Object, Object> entry : prop.entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
//通过指定的key获取value 如果找不到key,则返回null
String url = prop.getProperty("url");
System.out.println("url的值是"+url);
//getProperty(String key,String defaultValue)
//逻辑:通过指定的key,获取对应的value值,如果该key不存在,就返回默认值
String p1 = prop.getProperty("school", "哈工大");
System.out.println("p1的值是"+p1);
}
}
Exercise01
package com.se.zExercise;
import java.util.*;
/**
* 【中】设计一个方法,随机生成10个不重复的20以内的数字,存入一个List集合,
*/
public class Exercise0 {
public static void main(String[] args) {
Set<Integer> set = nums(10);
List<Integer> list = new ArrayList<>();
list.addAll(set);
System.out.println(list);
}
public static Set<Integer> nums(int length) {
//先创建一个set集合
Set<Integer> set = new HashSet<>();
do {
//随机
int num = (int) (Math.random() * 20);
//存储
set.add(num);
//set的长度不足,就继续
} while (set.size() < length);
return set;
}
}
Exercise02
package com.se.zExercise;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Exercise01_Max {
public static List<Integer> nums() {
List<Integer> nums = new ArrayList<>();
for (int i = 0; i < 20; i++) {
nums.add(i);
}
Collections.shuffle(nums);
return nums.subList(0, 10);
}
public static void main(String[] args) {
List<Integer> list = nums();
System.out.println(list);
}
}