https://www.nowcoder.com/tutorial/94/ae05554a3ad84e42b6f9fc4d52859dc4
https://how2j.cn/frontroute
https://how2j.cn/k/collection/collection-arraylist/363.html
概述
单列集合 Collection
双列集合 Map 字典
Collection接口:List接口、Set接口
List:有序,可重复
ArrayList、LinkedList、Vector
Set:无序,唯一不重复
HashSet、TreeSet
HashSet:LinkedHashSet
Map接口:HashTable 散列表、HashMap、TreeMap
HashMap:LinkedHashMap
同步问题
同步 = 线程安全
不同步是因为有些操作不是原子操作
有序问题
存放null问题
list
ArrayList
不同步
1.1 集合框架和数组
数组的局限性:
声明长度是 10 的数组
不用的数组浪费了
超过 10 又放不下…
为解决数组局限性,引入容器!
常见容器类:ArrayList
容器的容量 【capacity】 会随对象的增加,自动增加
不用担心越界
size:ArrayList 中元素数量
capacity:ArrayList 的容量
ArrayList 用 size 判断数组是否越界
package 第15个程序_集合框架.a1_ArrayList.s1_改进的数组_容器;
public class Hero {
public String name; // 名字
public float hp; // 护甲
public int damage; // 攻击力
public Hero(){}
public Hero(String name){
this.name = name;
}
public String toString(){
return name;
}
}
package 第15个程序_集合框架.a1_ArrayList.s1_改进的数组_容器;
import java.util.ArrayList;
public class test {
public static void main(String[] args) {
ArrayList heros = new ArrayList();
heros.add(new Hero("盖伦"));
System.out.println("容量 = " + heros.size());
heros.add(new Hero("提莫"));
System.out.println("容量 = " + heros.size());
}
}
1.2 常用方法
对象名.get(int c)
返回位置c对应的值
1.2.1 增
package 第15个程序_集合框架.a1_ArrayList.s2_常用方法;
import java.util.ArrayList;
public class test {
public static void main(String[] args) {
ArrayList heros = new ArrayList();
for (int i = 0; i < 5; i++){
heros.add(new Hero("hero " + i));
}
System.out.println(heros);
System.out.println();
Hero hero = new Hero("special hero");
heros.add(3, hero); // 在指定位置插入对象
System.out.println(heros.toString());
}
}
1.2.2 是否存在
public class test {
public static void main(String[] args) {
ArrayList heros = new ArrayList();
for (int i = 0; i < 5; i++){
heros.add(new Hero("hero " + i));
}
Hero special_hero = new Hero("special hero");
heros.add(3, special_hero); // 在指定位置插入对象
System.out.println(heros);
// 开始判断是否存在某对象
System.out.println("hero 1 是否存在? - " + heros.contains(new Hero("hero 1")));
System.out.println("special_hero 是否存在? - " + heros.contains(special_hero));
}
}
1.2.3 获取指定位置的对象
public class test {
public static void main(String[] args) {
ArrayList heros = new ArrayList();
for (int i = 0; i < 5; i++){
heros.add(new Hero("hero " + i));
}
Hero special_hero = new Hero("special hero");
heros.add(3, special_hero); // 在指定位置插入对象
System.out.println(heros);
System.out.println("位置4的对象 " + heros.get(4));
System.out.println("位置6的对象 " + heros.get(6));
}
}
1.2.4 获取指定对象的位置
public class test {
public static void main(String[] args) {
ArrayList heros = new ArrayList();
for (int i = 0; i < 5; i++){
heros.add(new Hero("hero " + i));
}
Hero special_hero = new Hero("special hero");
heros.add(3, special_hero); // 在指定位置插入对象
System.out.println(heros);
System.out.println("special_hero 的位置 = " + heros.indexOf(special_hero));
System.out.println("新英雄 hero 1 的位置 = " + heros.indexOf(new Hero("hero 1")));
}
}
1.2.5 删除
package 第15个程序_集合框架.a1_ArrayList.s2_常用方法.a5_删除;
import 第15个程序_集合框架.a1_ArrayList.s2_常用方法.Hero;
import java.util.ArrayList;
public class test {
public static void main(String[] args) {
ArrayList heros = new ArrayList();
for (int i = 0; i < 5; i++){
heros.add(new Hero("hero " + i));
}
Hero special_hero = new Hero("special hero");
heros.add(3, special_hero); // 在指定位置插入对象
System.out.println(heros);
System.out.println();
// 删除下标是2的对象
heros.remove(2);
System.out.println("删除下标是2的对象");
System.out.println(heros);
// 删除 special_hero 对象
heros.remove(special_hero);
System.out.println("删除 special_hero 对象");
System.out.println(heros);
}
}
1.2.6 替换
package 第15个程序_集合框架.a1_ArrayList.s2_常用方法.a6_替换;
import 第15个程序_集合框架.a1_ArrayList.s2_常用方法.Hero;
import java.util.ArrayList;
public class test {
public static void main(String[] args) {
ArrayList heros = new ArrayList();
for (int i = 0; i < 5; i++){
heros.add(new 第15个程序_集合框架.a1_ArrayList.s2_常用方法.Hero("hero " + i));
}
Hero special_hero = new Hero("special hero");
heros.add(3, special_hero); // 在指定位置插入对象
System.out.println(heros);
System.out.println();
heros.set(5, new Hero("hero x"));
System.out.println(heros);
}
}
heros.size()
获取大小
Hero hs[] = (Hero[])heros.toArray(new Hero[]{});
转为数组
heros.addAll(anotherHeros);
另一个ArrayList的元素都加入到当前ArrayList
heros.clear();
清空
1.2.7 练习1
判断集合里是否存在 name 等于 "hero 1"的对象
package 第15个程序_集合框架.a1_ArrayList.s2_常用方法.练习1;
import 第15个程序_集合框架.a1_ArrayList.s2_常用方法.Hero;
import java.util.ArrayList;
public class test {
public static void main(String[] args) {
ArrayList heros = new ArrayList();
for (int i = 0; i < 5; i++){
heros.add(new 第15个程序_集合框架.a1_ArrayList.s2_常用方法.Hero("hero " + i));
}
第15个程序_集合框架.a1_ArrayList.s2_常用方法.Hero special_hero = new Hero("special hero");
heros.add(3, special_hero); // 在指定位置插入对象
System.out.println(heros);
System.out.println();
String name = "hero 1";
int flag = 0;
for (int i = 0 ; i < heros.size(); i++){
Hero hero = (Hero)heros.get(i);
if(name.equals(hero.name)){
flag = 1;
System.out.println("存在!");
break;
}
}
if(flag == 0)
System.out.println("不存在!");
}
}
1.2.8 练习2
用 ArrayList 实现 MyStringBuffer
package 第15个程序_集合框架.a1_ArrayList.s2_常用方法.练习2;
public interface IStringBuffer {
public void append(String str); //追加字符串
public void append(char c); //追加字符
public void insert(int pos,char b); //指定位置插入字符
public void insert(int pos,String b); //指定位置插入字符串
public void delete(int start); //从开始位置删除剩下的
public void delete(int start,int end); //从开始位置删除结束位置-1
public void reverse(); //反转
public int length(); //返回长度
}
package 第15个程序_集合框架.a1_ArrayList.s2_常用方法.练习2;
import java.util.ArrayList;
public class MyStringBuffer implements IStringBuffer{
ArrayList list = new ArrayList();
@Override
public void append(String str) {
if (str == null)
return;
list.add(str);
}
@Override
public void append(char c) {
list.add(c);
}
@Override
public void insert(int pos, char b) {
if(pos<0 || pos > list.size())
return;
else
list.add(pos,b);
}
@Override
public void insert(int pos, String b) {
if(pos<0 || pos > list.size())
return;
list.add(pos,b);
}
@Override
public void delete(int start) {
delete(start,list.size());
}
@Override
public void delete(int start, int end) {
if(start<0 || start > list.size() || start > end || end > list.size() || end < 0)
return;
else{
for(int i = start; i < end; i++)
list.remove(start);
}
}
@Override
public void reverse() {
for (int i = 0; i < list.size()/2; i++){
char t = (char) list.get(i);
list.set(i,list.get(list.size()-i-1));
list.set(list.size()-i-1,t);
}
}
@Override
public int length() {
return list.size();
}
}
package 第15个程序_集合框架.a1_ArrayList.s2_常用方法.练习2;
public class test {
public static void main(String[] args) {
MyStringBuffer myStringBuffer = new MyStringBuffer();
myStringBuffer.append('1');
myStringBuffer.append('2');
myStringBuffer.append('3');
myStringBuffer.append("45");
System.out.println(myStringBuffer.list.toString());
System.out.println("删除第3个位置元素");
myStringBuffer.delete(3);
System.out.println(myStringBuffer.list.toString());
System.out.println("删除第1-2的位置元素们");
myStringBuffer.delete(1,2);
System.out.println(myStringBuffer.list.toString());
myStringBuffer.append('1');
myStringBuffer.append('2');
myStringBuffer.append('3');
System.out.println(myStringBuffer.list.toString());
myStringBuffer.reverse();
System.out.println("反转后:");
System.out.println(myStringBuffer.list.toString());
System.out.println("长度 = " + myStringBuffer.length());
}
}
1.3 泛型
package 第15个程序_集合框架.a1_ArrayList.s4_泛型.c1_简单程序;
import java.util.ArrayList;
import java.util.List;
public class test {
public static void main(String[] args) {
List heros = new ArrayList();
heros.add(new Hero("盖伦"));
heros.add(new Hero("冰杖"));
Hero h1 = (Hero) heros.get(1);
// 泛型
List<Hero> gheros = new ArrayList<>();
gheros.add(new Hero("盖伦"));
gheros.add(new ADHero());
Hero h2 = gheros.get(0);
}
}
1.4 遍历
for
for (Hero h : heros) {
System.out.println(h);
}
迭代器 Iterator
Iterator<Hero> it= heros.iterator();
while(it.hasNext()){
Hero h = it.next();
System.out.println(h);
}
迭代器 Iterator可以处理修改
Iterator<Hero> it= heros.iterator();
while(it.hasNext()){
Hero h = it.next();
if(?.equals(h))
it.remove();
}
ListIterator:
1.4.1 练习
package 第15个程序_集合框架.a1_ArrayList.s4_泛型.练习;
public class Hero {
public String name; // 名字
public float hp; // 护甲
public int damage; // 攻击力
public int number; // 编号
public Hero(){}
public Hero(String name, int number){
this.name = name;
this.number = number;
}
public String toString(){
return name;
}
}
package 第15个程序_集合框架.a1_ArrayList.s4_泛型.练习;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class test {
public static void main(String[] args) {
List<Hero> heroes = new ArrayList<>();
List<Hero> deletes = new ArrayList<>();
for (int i = 0; i < 100; i++){
Hero h = new Hero("hero " + i, i);
heroes.add(h);
}
Iterator<Hero> it = heroes.iterator();
while (it.hasNext()){
Hero h = it.next();
if(h.number%8 == 0){
deletes.add(h);
}
}
for(Hero h:deletes){
heroes.remove(h);
}
System.out.println(heroes);
}
}
LinkedList
有额外的get()、remove()、insert()
常用方法和 ArrayList常用方法
作为双链表
package 第15个程序_集合框架.a2_LinkedList.s1_简单程序;
import java.util.LinkedList;
public class test {
public static void main(String[] args) {
LinkedList<Hero> l = new LinkedList<>();
//在末尾插入
l.addLast(new Hero("hero 1"));
l.addLast(new Hero("hero 2"));
l.addLast(new Hero("hero 3"));
// 在前面插入
l.addFirst(new Hero("hero x"));
System.out.println(l + "\n");
System.out.println("查看最前面的英雄: \n" + l.getFirst());
System.out.println("查看最后面的英雄: \n" + l.getLast() + "\n");
System.out.println("取出最前面的英雄 \n" + l.removeFirst());
System.out.println("取出最后面的英雄 \n" + l.removeLast());
System.out.println(l);
}
}
作为队列Queue 双端队列Deque
https://www.geeksforgeeks.org/java-util-linkedlist-poll-pollfirst-polllast-examples-java/
offer 在最后添加元素
poll 取出第1个元素 并删除
peek 查看第1个元素
Dueue:
pollFirst():检索并删除此列表的第一个元素,如果此列表为空,则返回null
pollLast():检索并删除此列表的最后一个元素,如果此列表为空,则返回null
public static void main(String[] args) {
List ll =new LinkedList<Hero>();
//LinkedList 实现 Deque,又实现了 Queue
//Queue代表FIFO 先进先出的队列
Queue<Hero> q= new LinkedList<Hero>();
//加在队列的最后面
System.out.print("初始化队列:\t");
q.offer(new Hero("Hero1"));
q.offer(new Hero("Hero2"));
q.offer(new Hero("Hero3"));
q.offer(new Hero("Hero4"));
System.out.println(q);
System.out.print("把第一个元素取poll()出来:\t");
//取出第一个Hero,FIFO 先进先出
Hero h = q.poll();
System.out.println(h);
System.out.print("取出第一个元素之后的队列:\t");
System.out.println(q);
//把第一个拿出来看一看,但是不取出来
h=q.peek();
System.out.print("查看peek()第一个元素:\t");
System.out.println(h);
System.out.print("查看并不会导致第一个元素被取出来:\t");
System.out.println(q);
}
Dueue 子类—ArrayDeque
https://blog.csdn.net/yyoc97/article/details/88759562
ArrayDeque采用循环数组
用固定数组实现循环数组
2.1.3 练习
用 LinkedList 实现 Stack栈
package 第15个程序_集合框架.a2_LinkedList.s2_实现栈;
public class test {
public static void main(String[] args) {
MyStack myStack = new MyStack();
myStack.push(new Hero("盖伦"));
myStack.push(new Hero("提莫"));
myStack.get();
System.out.println("把最后一个英雄取出来:");
System.out.println(myStack.pull());
myStack.get();
System.out.println("查看最后一个英雄:");
System.out.println(myStack.peek());
myStack.get();
}
}
package 第15个程序_集合框架.a2_LinkedList.s2_实现栈;
public interface stack {
//把英雄推入到最后位置
public void push(Hero h);
//把最后一个英雄取出来
public Hero pull();
//查看最后一个英雄
public Hero peek();
}
package 第15个程序_集合框架.a2_LinkedList.s2_实现栈;
import java.util.Iterator;
import java.util.LinkedList;
public class MyStack implements stack{
private static LinkedList<Hero> list = new LinkedList<>();
//把英雄推入到最后位置
@Override
public void push(Hero h) {
list.addLast(h);
}
//把最后一个英雄取出来
@Override
public Hero pull() {
return list.removeLast();
}
//查看最后一个英雄
@Override
public Hero peek() {
return list.peekLast();
}
public void get(){
Iterator<Hero> it= list.iterator();
System.out.println("英雄有:");
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println();
}
}
package 第15个程序_集合框架.a2_LinkedList.s2_实现栈;
public class test {
public static void main(String[] args) {
MyStack myStack = new MyStack();
myStack.push(new Hero("盖伦"));
myStack.push(new Hero("提莫"));
myStack.get();
System.out.println("把最后一个英雄取出来:");
System.out.println(myStack.pull());
myStack.get();
System.out.println("查看最后一个英雄:");
System.out.println(myStack.peek());
myStack.get();
}
}
Vector
同步
Set
HashSet
元素 不能重复
不是按元素插入顺序排列
允许null
【添加】
add(value)
addAll(set)
【删除】
remove
removeAll,从 set 中批量删除部分数据
clear 清空
【其他】
size 元素的个数
isEmpty 判空
hashset 对于自定义对象,这个自定义对象需要重写 hashcode 和 equals 方法
package 第15个程序_集合框架.a2_LinkedList.s5_HashSet.c1_简单程序;
import java.util.HashSet;
public class test {
public static void main(String[] args) {
HashSet<String> names = new HashSet<String>();
names.add("盖伦");
System.out.println(names);
names.add("提莫");
System.out.println(names);
names.add("盖伦");
System.out.println(names);
}
}
2.4.1 遍历
https://www.zhihu.com/question/28414001
Java遍历HashSet 输出是有序的
package 第15个程序_集合框架.a2_LinkedList.s5_HashSet.c2_遍历;
import java.util.HashSet;
import java.util.Iterator;
public class test {
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<Integer>();
int length = 3000000;
for (int i = 0; i < length; i++){
hashSet.add(i);
}
// readFor1(hashSet);
// readFor2(hashSet);
readWhile(hashSet);
}
public static void readFor1(HashSet<Integer> hashSet){
double start = System.currentTimeMillis();
int i = 0;
System.out.println("元素个数 = " + hashSet.size());
for (Iterator<Integer> iterator = hashSet.iterator(); iterator.hasNext();){
System.out.print( (Integer) iterator.next() + " ");
i++;
if( i%20 == 0)
System.out.println();
}
double end = System.currentTimeMillis();
System.out.println("\n用时 = " + (end - start) + " ms");
}
public static void readFor2(HashSet<Integer> hashSet){
double start = System.currentTimeMillis();
int i = 0;
System.out.println("元素个数 = " + hashSet.size());
for (Integer n:hashSet){
System.out.print(n + " ");
i++;
if( i%20 == 0)
System.out.println();
}
double end = System.currentTimeMillis();
System.out.println("\n用时 = " + (end - start) + " ms");
}
public static void readWhile(HashSet<Integer> hashSet){
double start = System.currentTimeMillis();
int i = 0;
System.out.println("元素个数 = " + hashSet.size());
Iterator<Integer> iterator = hashSet.iterator();
while (iterator.hasNext()){
System.out.print( (Integer) iterator.next() + " ");
i++;
if( i%20 == 0)
System.out.println();
}
double end = System.currentTimeMillis();
System.out.println("\n用时 = " + (end - start) + " ms");
}
}
2.4.2 与 HashMap 的关系
HashSet 基于 HashMap 而实现
HashSet.add = HashMap.put
HashMap 较快,用唯一的键来获取对象
2.4.3 练习
创建长度 100 的字符串数组
用长度是 2 的随机字符填充该字符串数组
统计重复字符串有多少
用 HashSet 解决
package 第15个程序_集合框架.a2_LinkedList.s5_HashSet.练习;
import java.util.HashSet;
public class test {
public String myRand(int length){
String string = "";
for (int i = 0; i < length; i++){
string += (char)(Math.random()*(122-48+1)+48);
}
return string;
}
public void print(String[] strings){
System.out.println("\n输出:");
int i = 1;
for (String string:strings){
System.out.printf("%-2d:%s ",i ,string);
if(i%20==0)
System.out.println();
i++;
}
System.out.println();
}
public void init(String[] strings){
int length = strings.length;
for (int i = 0; i < length; i++){
strings[i] = myRand(2);
}
System.out.println("初始化成功!");
print(strings);
}
public void tongji(String[] strings){
HashSet<String> set = new HashSet<String>();
HashSet<String> res = new HashSet<String>();
for(String string: strings){
if(set.add(string) == false)
res.add(string);
}
System.out.println("有 " + res.size() + " 个重复元素");
System.out.println("分别是 " + res);
}
public static void main(String[] args) {
int length = 200;
String[] strings = new String[length];
new test().init(strings);
new test().tongji(strings);
}
}
TreeSet
同HashSet比,多了排序
public class test {
public static void main(String[] args) {
TreeSet<Double> s = new TreeSet<Double>();
for (int i = 0; i < 10; i++){
Random r =new Random();
double t = r.nextDouble()*100%71+30;
DecimalFormat df =new java.text.DecimalFormat("#.0");
s.add(Double.valueOf(df.format(t)));
}
Iterator<Double> it = s.iterator();
System.out.println("成绩由低到高:");
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("\n不及格的成绩:");
SortedSet<Double>s1 = s.headSet(60.0);
for(double t:s1)
System.out.println(t);
System.out.println("\n90以上的成绩:");
SortedSet<Double>s2 = s.tailSet(90.0);
for(double t:s2)
System.out.println(t);
}
}
Map
HashMap
https://blog.csdn.net/weixin_30578677/article/details/97116606
key - value
key 不可以重复!
对象名.keySet()
键的集合
public class test {
public static void main(String[] args) {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("adc", "物理英雄");
hashMap.put("ap", " 魔法英雄");
hashMap.put("t", "坦克");
System.out.println(hashMap.get("t"));
}
}
public class Hero {
public String name; // 名字
public float hp; // 护甲
public int damage; // 攻击力
public Hero(){}
public Hero(String name){
this.name = name;
}
public String toString(){
return name;
}
}
public class test {
public static void main(String[] args) {
HashMap<String, Hero> heroHashMap = new HashMap<String, Hero>();
heroHashMap.put("盖伦", new Hero("盖伦1"));
System.out.println(heroHashMap);
System.out.println();
heroHashMap.put("盖伦", new Hero("盖伦2"));
System.out.println(heroHashMap);
System.out.println();
heroHashMap.clear();
Hero hero = new Hero("盖伦");
heroHashMap.put("hero1", hero);
heroHashMap.put("hero2", hero);
System.out.println(heroHashMap);
}
}
public class test {
public static void main(String[] args) {
Map map = new HashMap();
map.put("1","asd");
map.put("2","zxc");
map.put("3","qwe");
Set keyset = map.keySet();
Iterator it = keyset.iterator();
while (it.hasNext()){
Object key = it.next();
Object value = map.get(key);
System.out.println(key + " : " + value);
}
Set keyset1 = map.entrySet();
Iterator it1 = keyset1.iterator();
while (it1.hasNext()){
Object key = it1.next();
System.out.println(key);
}
}
}
复杂用法
https://segmentfault.com/a/1190000039756899
put返回旧值,如果没有则返回null
compute返回新值,当key不存在时,执行value计算方法,计算value
putIfAbsent返回旧值,如果没有则返回null
先计算value,再判断key是否存在
computeIfAbsent:存在时返回存在的值,不存在时返回新值
参数为:key,value计算方法
先判断key是否存在,再执行value计算方法
https://www.bmabk.com/index.php/post/13663.html
Map<String, String> map = new HashMap<>();
// 原来的方法
if (!map.containsKey("huawei")) {
map.put("huawei", "huawei" + "华为");
}
// 同上面方法效果一样,但更简洁
map.computeIfAbsent("huawei", k -> k + "华为");
System.out.println(map);
2.3.3 练习
准备 ArrayList,放 3000000(三百万个) Hero对象,其名称随机,格式 hero-[4位随机数]
hero-3229
hero-6232
hero-9365
…
总数很大,所以几乎每种都有重复,把名字叫做 hero-5555的所有对象找出来
要求使用 2 种办法来寻找
1 不用 HashMap,用 for 循环找,统计费时
2 借助 HashMap,找出结果,并统计花费的时间
public class Hero {
public String name; // 名字
public float hp; // 护甲
public int damage; // 攻击力
public Hero(){}
public Hero(String name){
this.name = name;
}
public String toString(){
return name;
}
}
public class test {
public static void main(String[] args) {
int lenght = 3000000;
Hero[] heroes = new Hero[lenght];
HashMap<String, ArrayList<Hero>> heroHashMap = new HashMap<String, ArrayList<Hero>>();
for (int i = 0; i < lenght; i++){
heroes[i] = new Hero("hero - " + (new Random().nextInt(9000)+1000));
if(heroHashMap.containsKey(heroes[i].name)){
heroHashMap.get(heroes[i].name).add(heroes[i]);
}else {
heroHashMap.put(heroes[i].name, new ArrayList<Hero>());
heroHashMap.get(heroes[i].name).add(heroes[i]);
}
}
String name = "hero - 5555";
searchFor(heroes, name);
searchHashmap(heroHashMap, name);
}
public static void searchHashmap(HashMap<String, ArrayList<Hero>> heroHashMap, String name){
double start = System.currentTimeMillis();
int c = heroHashMap.get(name).size();
System.out.println("统计其数量是 = " + c);
double end = System.currentTimeMillis();
System.out.println("用时 = " + (end - start) + "ms\n");
}
public static void searchFor(Hero[] heroes, String name){
double start = System.currentTimeMillis();
int c = 0;
for (Hero hero:heroes){
if(hero.name.equals(name))
c++;
}
System.out.println("统计其数量是 = " + c);
double end = System.currentTimeMillis();
System.out.println("用时 = " + (end - start) + "ms\n");
}
}
TreeMap
key - value
key 不可以重复!通过二叉树保证key的唯一
会对key自然排序
public class t2 {
public static void main(String[] args) {
Map<String,String > map = new TreeMap<>();
map.put("5","小米");
map.put("1","小明");
map.put("1","小米");
Set keys = map.entrySet();
Iterator iterator = keys.iterator();
while (iterator.hasNext()){
Map.Entry e = (Map.Entry) iterator.next();
System.out.println(e.getKey() + " " + e.getValue());
}
}
}
1 小米
5 小米
3 关系与区别
同步问题
同步 = 线程安全
不同步是因为有些操作不是原子操作
有序问题
存放null问题
3.1 ArrayList vs HashSet
ArrayList: 有顺序
HashSet: 无顺序
ArrayLis 数据可重复
HashSet 数据不可重复
3.1.1 练习
生成 50 个 0 - 9999 随机数,不能有重复
package 第15个程序_集合框架.a3_关系与区别.s1.练习;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
public class test {
public static void main(String[] args) {
int length = 50;
int range = 9999;
HashSet<Integer> hashSet = new HashSet<>();
while (hashSet.size()<length){
hashSet.add(new Random().nextInt(range+1));
}
Iterator<Integer> iterator = hashSet.iterator();
int i = 0;
while(iterator.hasNext()){
System.out.printf("%-5d ",iterator.next());
i++;
if(i%10 == 0)
System.out.println();
}
}
}
3.2 ArrayList vs LinkedList
就是 顺序表 和 链表 的区别
3.2.1 插入数据
在最前面插入数据
list.add(0,number); // 一直在位置0处插入数据
package 第15个程序_集合框架.a3_关系与区别.s2_ArrayList_vs_LinkedList.c1_插入数据;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class test {
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new LinkedList<>();
insertFirst(list1,"ArrayList");
insertFirst(list2, "LinkedList");
}
public static void insertFirst(List<Integer> list, String type){
double start = System.currentTimeMillis();
int total = 100000;
final int number = 5;
for (int i = 0; i < total; i++){
list.add(0,number); // 一直在位置0处插入数据
}
double end = System.currentTimeMillis();
System.out.printf("在 %s 最前面, 插入 %d 条数据, 共耗时 %f ms\n", type, total, (end - start));
}
}
3.2.2 定位
List<Integer> l = new ArrayList<>();
int n = l.get(200); // 取位置是 200 的元素
3.2.3 练习1
实现:
在末尾插入数据
在中间位置插入数据
package 第15个程序_集合框架.a3_关系与区别.s2_ArrayList_vs_LinkedList.c1_插入数据.练习;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class test {
public static void main(String[] args) {
List<Integer> lista1 = new ArrayList<>();
List<Integer> listb1 = new LinkedList<>();
insert_end(lista1,"ArrayList");
insert_end(listb1,"ArrayList");
List<Integer> lista2 = new ArrayList<>();
List<Integer> listb2 = new LinkedList<>();
insert_end(lista2,"ArrayList");
insert_end(listb2,"ArrayList");
}
public static void insert_end(List<Integer> list, String type){
double start = System.currentTimeMillis();
int total = 100000;
final int number = 5;
for (int i = 0; i < total; i++){
list.add(i,number);
}
double end = System.currentTimeMillis();
System.out.printf("在 %s 最后面, 插入 %d 条数据, 共耗时 %f ms\n", type, total, (end - start));
}
public static void insert_middle(List<Integer> list, String type){
double start = System.currentTimeMillis();
int total = 100000;
final int number = 5;
for (int i = 0; i < total; i++){
list.add(i/2,number);
}
double end = System.currentTimeMillis();
System.out.printf("在 %s 中间, 插入 %d 条数据, 共耗时 %f ms\n", type, total, (end - start));
}
}
3.3 Set
3.3.1 HashSet vs LinkedHashSet vs TreeSet
HashSet: 无序
LinkedHashSet: 按照插入顺序
TreeSet: 从小到大排序
Set 集合:不允许对象有重复的值
List:允许有重复,它对集合中的对象进行索引
Queue:工作原理是 FCFS 算法 (First Come, First Serve)
package 第15个程序_集合框架.a3_关系与区别.s4_Set.c1_简单程序;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
public class test {
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
hashSet.add(2);hashSet.add(8);hashSet.add(88);
System.out.println(hashSet);
LinkedHashSet<Integer> hashSet1 = new LinkedHashSet<>();
hashSet1.add(2);hashSet1.add(8);hashSet1.add(88);
System.out.println(hashSet1);
TreeSet<Integer> hashSet2 = new TreeSet<>();
hashSet2.add(2);hashSet2.add(8);hashSet2.add(88);
System.out.println(hashSet2);
}
}
3.3.2 练习
利用 LinkedHashSet 的既不重复,又有顺序的特性
把 Math.PI 中的数字,按出现顺序打印出来,相同数字,只出现一次
package 第15个程序_集合框架.a3_关系与区别.s4_Set.练习;
import java.util.LinkedHashSet;
import java.util.Set;
public class test {
public static void main(String[] args) {
Set<Integer> set = new LinkedHashSet<>();
char[] cs = String.valueOf(Math.PI).replace(".", "").toCharArray();
for (char t: cs){
set.add(Integer.parseInt(String.valueOf(t)));
}
System.out.println(set);
}
}
HashMap vs LinkedHashMap
HashMap 无序
LinkedHashMap 保持输入顺序
3.4 HashMap vs Hashtable
HashMap、Hashtable 都实现了 Map 接口,都是键值对保存数据的方式
区别1:
HashMap 可放 null
Hashtable 不能 null
区别2:
HashMap 不线程安全,是类
Hashtable 线程安全的类
public static void main(String[] args) {
//HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式
HashMap<String,String> hashMap = new HashMap<String,String>();
//HashMap可以用null作key,作value
hashMap.put(null, "123");
hashMap.put("123", null);
Hashtable<String,String> hashtable = new Hashtable<String,String>();
//Hashtable不能用null作key,不能用null作value
hashtable.put(null, "123");
hashtable.put("123", null);
}
3.4.1 练习
用如下键值对,初始化 HashMap
adc - 物理英雄
apc - 魔法英雄
t - 坦克
对这个 HashMap 进反转,key 变成 value,value 变成 key
提示: keySet()可以获取所有的key, values()可以获取所有的value
法1
public class test {
public static void main(String[] args) {
HashMap<String, String> hashMap1 = new HashMap<>();
hashMap1.put("adc "," 物理英雄");
hashMap1.put("ap "," 魔法英雄");
hashMap1.put("t","坦克");
System.out.println(hashMap1);
HashMap<String, String> hashMap2 = new HashMap<>();
Set<Map.Entry<String, String>> entryMap = hashMap1.entrySet();
for (Map.Entry<String, String> e: entryMap){
String key = e.getKey();
String value = e.getValue();
hashMap2.put(value, key);
}
System.out.println(hashMap2);
}
}
法2:
package 第15个程序_集合框架.a3_关系与区别.s3_HashMap_vs_Hashtable.练习;
import java.util.HashMap;
public class test2 {
public static void main(String[] args) {
HashMap<String, String> hashMap1 = new HashMap<>();
hashMap1.put("adc "," 物理英雄");
hashMap1.put("ap "," 魔法英雄");
hashMap1.put("t","坦克");
System.out.println(hashMap1);
Object[] objectKey = hashMap1.keySet().toArray();
Object[] objectValue = hashMap1.values().toArray();
hashMap1.clear();
for (int i = 0; i < objectKey.length; i++){
hashMap1.put(objectValue[i].toString(), objectKey[i].toString());
}
System.out.println(hashMap1);
}
}
LinkedList / Deque中 add/offer/push,remove/pop/poll
https://www.jianshu.com/p/ae28d514003c
add和remove是一对,源自Collection接口
offer和poll是一对,源自Queue
队列
offerFirst / offerLast 和 pollFirst / pollLast是一对,源自Deque
双端队列
push和pop是一对,源自Deque栈(Stack类官方已不建议使用,应用Deque代替)
4 其他
4.1 hashcode(散列值) 原理
4.1.1 HashMap
HashMap 性能卓越(查找元素非常快),空间换时间
每个要存储的元素给一个特殊的 hashcode 算法,得到其位置数
若该位置已经有元素了,就在其元素后面插入,在该位置形成【链表】
4.1.2 HashSet
HashSet 的内壳是 HashMap
若 hashcode 不同,就是不重复
若 hashcode 一样,还要进行 equals 比较
若 equals 一样,就 重复数据
若 equals 不同,就是 不同数据
4.1 3 练习1 自定义 hashcode
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
是 String 的 hashcode 生成办法
s[0] 表示第1位字符
n 表示字符串的长度
自定义简单的 hashcode 算法,计算任意字符串的 hashcode
public static int hashcode(String)
若字符串长度是0,就返回0
否则 获取每一位字符,转成数字后,相加,最后乘以23
(s[0]+ s[1] + s[2] + s[3]+ s[n-1])*23
如果值超过了1999,则取2000的余数,保证落在0-1999之间。
如果是负数,则取绝对值
package 第15个程序_集合框架.a4_其他.s1_hashcode.练习;
import java.util.Random;
public class test {
public static void main(String[] args) {
String string = randString(new Random().nextInt(100));
int hash_code = hashcode(string);
System.out.println("hashCode = " + hash_code);
}
public static int hashcode(String string){
if (string.length() == 0)
return 0;
int hashcode = 0;
for (char t:string.toCharArray()){
hashcode += t;
}
hashcode *= 23;
// 取绝对值
hashcode = hashcode < 0 ? (0 - hashcode) : hashcode;
// 落在 0 - 1999
hashcode = hashcode%2000;
return hashcode;
}
public static String randString(int length){
String rand = "";
for (int i = 0; i < length; i++){
char t = (char)(Math.random()*(122-48+1)+48);
rand += t;
}
System.out.println("randString = " + rand);
return rand;
}
}
4.1 4 练习2 自定义 MyHashMap
HashMap 内部是长度 2000 的对象数组
put(String key,Object value)
Object get(String key)
package 第15个程序_集合框架.a4_其他.s1_hashcode.练习2;
public interface IHashMap {
public void put(String key,Object value);
public Object get(String key);
}
package 第15个程序_集合框架.a4_其他.s1_hashcode.练习2;
public class Entry {
String key;
Object value;
public Entry(Object key, Object value){
super();
this.key = key;
this.value = value;
}
@Override
public String toString() {
return "[key = " + key + " ], [ value = " + value + " ]";
}
}
package 第15个程序_集合框架.a4_其他.s1_hashcode.练习2;
public class Hero {
public String name; // 名字
public float hp; // 护甲
public int damage; // 攻击力
public Hero(){}
public Hero(String name){
this.name = name;
}
public String toString(){
return name;
}
public String getName() {
return name;
}
}
性能测试:
准备ArrayList,存放 3000000 个 Hero,名称 hero - [4位随机数]
hero - 3229
hero - 6232
hero - 9365
因为总数大,所以有重复,把 hero-5555 的所有对象找出来
用 2 种办法
1 不用 MyHashMap,直接用 for 循环找统计费时
2 借助 MyHashMap 找,统计费时
package 第15个程序_集合框架.a4_其他.s1_hashcode.练习2;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
public class MyHashMap implements IHashMap{
LinkedList<Entry>[] list = new LinkedList[2000];
@Override
public void put(String key, Object value) {
Entry entry = new Entry(key, value);
int code = hashCode(key);
if (list[code] != null){
list[code].add(entry);
} else {
list[code] = new LinkedList<>();
}
}
@Override
public Object get(String key) {
int code = hashCode(key);
if (list[code] != null){
Object object = null;
for (Entry e:list[code]){
if(e.key.equals(key)) {
object = e.value;
return object;
}
}
}
return null;
}
public int hashCode(String string){
if (string.length() == 0)
return 0;
int hashcode = 0;
for (char t:string.toCharArray()){
hashcode += t;
}
hashcode *= 23;
// 取绝对值
hashcode = hashcode < 0 ? (0 - hashcode) : hashcode;
// 落在 0 - 1999
hashcode = hashcode%2000;
return hashcode;
}
public static void main(String[] args) {
double start = System.currentTimeMillis();
System.out.println("正在初始化...");
ArrayList<Hero> arrayList = new ArrayList<>();
int length = 3000000;
for(int i = 0; i < length; i++){
arrayList.add( new Hero("hero - " + ((int) (Math.random()*9000) + 1000)) );
}
HashMap<String, ArrayList<Hero>> hashMap = new HashMap<>();
for(Hero hero:arrayList){
ArrayList<Hero> list = hashMap.get(hero.getName());//不是new一个list! 名字相同的hero, 放在一个List中,作为value
if (list == null){
list = new ArrayList<>();
hashMap.put(hero.getName(), list);
}
list.add(hero); // 相当于加入 hashMap 中了
}
MyHashMap myHashMap = new MyHashMap();
for (Hero hero:arrayList){
ArrayList<Hero> list = (ArrayList<Hero>) myHashMap.get(hero.getName());
if (list == null){
list = new ArrayList<>();
myHashMap.put(hero.getName(), list);
}
list.add(hero);
}
System.out.println("初始化完成!");
double end = System.currentTimeMillis();
System.out.println("用时 = " + (end - start) + " ms\n");
String name = "hero - 5555";
System.out.println("开始性能测试:");
searchOfHashMap(hashMap,name);
searchOfMyHashMap(myHashMap,name);
}
public static void searchOfHashMap(HashMap<String, ArrayList<Hero>> hashMap, String name){
double start = System.currentTimeMillis();
ArrayList<Hero> list = hashMap.get(name);
double end = System.currentTimeMillis();
if (list != null)
System.out.println("用 HashMap 找到 " + list.size() + " 个 " + name + " 对象");
else
System.out.println("用 HashMap 找到 0 个 " + name + " 对象");
System.out.println("用时 = " + (end - start) + " ms");
}
public static void searchOfMyHashMap(MyHashMap myHashMap, String name){
double start = System.currentTimeMillis();
ArrayList<Hero> list = (ArrayList<Hero>) myHashMap.get(name);
double end = System.currentTimeMillis();
if (list != null)
System.out.println("用 MyHashMap 找到 " + list.size() + " 个 " + name + " 对象");
else
System.out.println("用 MyHashMap 找到 0 个 " + name + " 对象");
System.out.println("用时 = " + (end - start) + " ms");
}
}
4.2 比较器
4.2.1 Comparator 排序
Hero 有 3 个属性,根据哪个属性进行排序?
public class Hero {
public String name;
public float hp;
public int damage;
public Hero(String name) {
this.name = name;
}
public String toString() {
return "Hero [name=" + name + ", hp=" + hp + ", damage=" + damage + "]\r\n";
}
public Hero(String name, int hp, int damage) {
this.name = name;
this.hp = hp;
this.damage = damage;
}
}
public class test {
public static void main(String[] args) {
Random random = new Random();
List<Hero> heroes = new ArrayList<>();
for (int i = 0; i < 10; i++){
heroes.add(new Hero("hero " + i, random.nextInt(100), random.nextInt(100)) );
}
System.out.println("初始化后: ");
System.out.println(heroes);
/*
直接 Collections.sort(heros); 会报错,因为排序标准不知道!
*/
System.out.println("尝试排序... ");
Comparator<Hero> c = new Comparator<Hero>() {
@Override
public int compare(Hero o1, Hero o2) {
if (o1.hp >= o2.hp) // 升序排列
return 1;
else
return -1;
}
};
Collections.sort(heroes, c);
System.out.println("成功!");
System.out.println(heroes);
}
}
Comparator 是接口,也可以让类直接实现这个接口
4.2.2 Comparable 排序
public class Hero implements Comparable<Hero>{
public String name;
public float hp;
public int damage;
public Hero(String name) {
this.name = name;
}
public String toString() {
return "Hero [name=" + name + ", hp=" + hp + ", damage=" + damage + "]\r\n";
}
public Hero(String name, int hp, int damage) {
this.name = name;
this.hp = hp;
this.damage = damage;
}
@Override
public int compareTo(Hero o) {
if (damage < o.damage) // 降序排列
return 1;
else
return -1;
}
}
public class test {
public static void main(String[] args) {
Random random = new Random();
List<Hero> heroes = new ArrayList<>();
for (int i = 0; i < 10; i++){
heroes.add(new Hero("hero " + i, random.nextInt(100), random.nextInt(100)) );
}
System.out.println("初始化后: ");
System.out.println(heroes);
System.out.println("尝试排序...");
Collections.sort(heroes);
System.out.println("成功!");
System.out.println(heroes);
}
}
4.2.3 练习1
TreeSet 中数据【默认】从小到大排序
TreeSet 构造方法支持传入 Comparator
public TreeSet(Comparator comparator)
使数字从大到小排
package 第15个程序_集合框架.a4_其他.s2_比较器.练习1;
import java.util.Comparator;
import java.util.TreeSet;
public class test {
public static void main(String[] args) {
TreeSet<Integer> treeSet = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return (o2 - o1);
}
});
for (int i = 0; i < 10; i++){
treeSet.add(i);
}
int t = 0;
for (Integer i:treeSet){
System.out.printf(i+" ");
t++;
if (t%5 == 0)
System.out.println();
}
}
}
4.2.4 练习2
借助 Comparable 接口,使 Item 具备按照价格从高到低排序。
初始化 10 个 Item,并且用 Collections.sort 进行排序,查看排序结果
package 第15个程序_集合框架.a4_其他.s2_比较器.练习2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class test {
public static void main(String[] args) {
List<Item> list = new ArrayList<>();
for (int i = 0; i < 10; i++){
list.add(new Item("Item " + i, (int) (Math.random()*100+1)));
}
System.out.println(list);
Collections.sort(list);
System.out.println("\n按照 price 降序排序:");
System.out.println(list);
}
}
4.3 聚合操作
和 Lambda 表达式 很紧密!
如:
String name =heros
.stream()
.sorted((h1,h2)->h1.hp>h2.hp?-1:1)
.skip(2)
.map(h->h.getName())
.findFirst()
.get();
public class Hero {
public String name;
public float hp;
public int damage;
public Hero(String name) {
this.name = name;
}
public String getName(){
return name;
}
public String toString() {
return "Hero [name=" + name + ", hp=" + hp + ", damage=" + damage + "]\r\n";
}
public Hero(String name, int hp, int damage) {
this.name = name;
this.hp = hp;
this.damage = damage;
}
}
public class test {
public static void main(String[] args) {
Random r = new Random();
List<Hero> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(new Hero("hero - " + i, r.nextInt(100), r.nextInt(100)));
}
System.out.println(list);
Collections.sort(list, new Comparator<Hero>() {
@Override
public int compare(Hero o1, Hero o2) {
return (int) (o2.hp - o1.hp);
}
});
Hero hero = list.get(2);
System.out.println("传统方式找出 hp 第3高的英雄是 " + hero.name);
// 聚合方式
String name = list
.stream()
.sorted((hero1,hero2)->hero1.hp>hero2.hp ? -1:1)
.skip(2)
.map(h -> h.getName())
.findFirst()
.get();
System.out.println("聚合方法找出 hp 第3高的英雄是 " + name);
}
}
4.4 遍历 迭代器 Iterator
public class t1 {
public static void main(String[] args) {
Collection<Integer> c = new ArrayList<Integer>();
c.add(1);
c.add(13);
c.add(31);
c.add(51);
c.add(17);
c.add(19);
Iterator<Integer> iterator = c.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
4.4 else
Collection 接口
Collections
Collections 是类,容器的工具类,同 Arrays 是数组的工具类
Collection 是接口
2.6 1 反转 reverse
public static void main(String[] args) {
//初始化集合numbers
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
numbers.add(i);
}
System.out.println("集合中的数据:");
System.out.println(numbers);
Collections.reverse(numbers);
System.out.println("翻转后集合中的数据:");
System.out.println(numbers);
}
2.6.2 打混 shuffle
public static void main(String[] args) {
//初始化集合numbers
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
numbers.add(i);
}
System.out.println("集合中的数据:");
System.out.println(numbers);
Collections.shuffle(numbers);
System.out.println("混淆后集合中的数据:");
System.out.println(numbers);
}
2.6.3 排序
public static void main(String[] args) {
//初始化集合numbers
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
numbers.add(i);
}
System.out.println("集合中的数据:");
System.out.println(numbers);
Collections.shuffle(numbers);
System.out.println("混淆后集合中的数据:");
System.out.println(numbers);
Collections.sort(numbers);
System.out.println("排序后集合中的数据:");
System.out.println(numbers);
}
2.6.4 交换
public static void main(String[] args) {
//初始化集合numbers
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
numbers.add(i);
}
System.out.println("集合中的数据:");
System.out.println(numbers);
Collections.swap(numbers,0,5);
System.out.println("交换0和5下标的数据后,集合中的数据:");
System.out.println(numbers);
}
2.6.5 向右滚动
public static void main(String[] args) {
//初始化集合numbers
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
numbers.add(i);
}
System.out.println("集合中的数据:");
System.out.println(numbers);
Collections.rotate(numbers,2);
System.out.println("把集合向右滚动2个单位,标的数据后,集合中的数据:");
System.out.println(numbers);
}
2.6.6 线程安全
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
System.out.println("把非线程安全的List转换为线程安全的List");
List<Integer> synchronizedNumbers = (List<Integer>) Collections.synchronizedList(numbers);
}
2.6.7 练习
先初始化一个List,长度是10,值是0-9。
然后不断的shuffle,直到前3位出现
3 1 4
shuffle 1000,000 次,统计出现的概率
public class test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0 ; i < 10; i++){
list.add(i);
}
double start = System.currentTimeMillis();
int c = 1000000;
int t = 0;
for (int i = 0 ; i < c; i++){
Collections.shuffle(list);
if(new test().yes(list) == 1)
t++;
}
System.out.println("概率 = " + (double)(t*100)/c + "%");
double end = System.currentTimeMillis();
System.out.println("用时 = " + (end - start) + " ms");
}
public int yes(List<Integer> list){
if(list.get(0) == 3 && list.get(1) == 1 && list.get(2) == 4)
return 1;
else
return 0;
}
}
其他集合
Queue Deque
2.2 二叉树
2.2.1 结点
public class Node {
//左孩子
public Node leftNode;
//右孩子
public Node rightNode;
//该结点的值
public Object value;
}
2.2.2 插入数据
小 放左子树
大 放右子树
public class Node {
//左孩子
public Node leftNode;
//右孩子
public Node rightNode;
//该结点的值
public Object value;
public void add(Object v){
if(value == null)
value = v;
else {
//小数要放在左子树
if ((Integer)v - (Integer)value <= 0){
if(leftNode == null){
leftNode = new Node();
}
leftNode.add(v);
}
else {//大数要放在右子树
if(rightNode == null){
rightNode = new Node();
}
rightNode.add(v);
}
}
}
public static void main(String[] args) {
int[] randoms = new int[]{2,4,12,34,2};
Node nodes = new Node();
for (int n:randoms){
nodes.add(n);
}
}
}
2.2.3 遍历
package 第15个程序_集合框架.a2_LinkedList.s3_二叉树.c2_插入;
import java.util.LinkedList;
public class Node {
//左孩子
public Node leftNode;
//右孩子
public Node rightNode;
//该结点的值
public Object value;
public void add(Object v){
if(value == null)
value = v;
else {
//小数要放在左子树
if ((Integer)v - (Integer)value <= 0){
if(leftNode == null){
leftNode = new Node();
}
leftNode.add(v);
}
else {//大数要放在右子树
if(rightNode == null){
rightNode = new Node();
}
rightNode.add(v);
}
}
}
// 前序遍历
public void proRead(){
System.out.println(value);
if (leftNode != null)
leftNode.proRead();
if(rightNode != null)
rightNode.proRead();
}
// 中序遍历
public void inderRead(){
if (leftNode != null)
leftNode.inderRead();
System.out.println(value);
if(rightNode != null)
rightNode.inderRead();
}
//后序遍历
public void postRead(){
if (leftNode != null)
leftNode.postRead();
if(rightNode != null)
rightNode.postRead();
System.out.println(value);
}
// 层次遍历
public void levelRead(){
LinkedList<Node> list = new LinkedList<>();
list.push(this);
while (!list.isEmpty()){
Node node = list.peek(); // 取元素
list.pop(); // 出栈
System.out.println(node.value);
if(node.leftNode != null)
list.push(node.leftNode);
if (node.rightNode!=null){
list.push(node.rightNode);
}
}
}
public static void main(String[] args) {
int[] randoms = new int[]{2,4,12,34,2};
Node nodes = new Node();
for (int n:randoms){
nodes.add(n);
}
System.out.println();
nodes.proRead();
System.out.println();
nodes.inderRead();
System.out.println();
nodes.postRead();
System.out.println();
nodes.levelRead();
System.out.println();
}
}