Java11-集合框架

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 判断数组是否越界

package15个程序_集合框架.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;
    }
}
package15个程序_集合框架.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 增
package15个程序_集合框架.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 删除
package15个程序_集合框架.a1_ArrayList.s2_常用方法.a5_删除;

import15个程序_集合框架.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 替换
package15个程序_集合框架.a1_ArrayList.s2_常用方法.a6_替换;

import15个程序_集合框架.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(new15个程序_集合框架.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"的对象

package15个程序_集合框架.a1_ArrayList.s2_常用方法.练习1;

import15个程序_集合框架.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(new15个程序_集合框架.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

package15个程序_集合框架.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(); //返回长度
}
package15个程序_集合框架.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();
    }
}
package15个程序_集合框架.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 泛型

package15个程序_集合框架.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 练习

package15个程序_集合框架.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;
    }
}
package15个程序_集合框架.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常用方法

作为双链表

package15个程序_集合框架.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栈

package15个程序_集合框架.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();
    }
}
package15个程序_集合框架.a2_LinkedList.s2_实现栈;

public interface stack {
    //把英雄推入到最后位置
    public void push(Hero h);

    //把最后一个英雄取出来
    public Hero pull();

    //查看最后一个英雄
    public Hero peek();
}
package15个程序_集合框架.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();
    }
}
package15个程序_集合框架.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 方法

package15个程序_集合框架.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 输出是有序的

package15个程序_集合框架.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 解决

package15个程序_集合框架.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 随机数,不能有重复

package15个程序_集合框架.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处插入数据

package15个程序_集合框架.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

实现:
在末尾插入数据
在中间位置插入数据

package15个程序_集合框架.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)

package15个程序_集合框架.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 中的数字,按出现顺序打印出来,相同数字,只出现一次

package15个程序_集合框架.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:

package15个程序_集合框架.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之间。
如果是负数,则取绝对值

package15个程序_集合框架.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)

package15个程序_集合框架.a4_其他.s1_hashcode.练习2;

public interface IHashMap {
    public  void  put(String key,Object value);
    public Object get(String key);
}
package15个程序_集合框架.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 + " ]";
    }
}
package15个程序_集合框架.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 找,统计费时

package15个程序_集合框架.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) 使数字从大到小排

package15个程序_集合框架.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 进行排序,查看排序结果

package15个程序_集合框架.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 遍历

package15个程序_集合框架.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();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1403034144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值