【集合系列】TreeMap 集合

news2025/1/19 2:37:34

TreeMap 集合

    • 1. 概述
    • 2. 方法
    • 3. 遍历方式
    • 4. 排序方式
    • 5. 代码示例1
    • 6. 代码示例2
    • 7. 代码示例3
    • 8. 注意事项
    • 9. 源码分析

其他集合类

父类 Map

集合类的遍历方式

TreeSet 集合

具体信息请查看 API 帮助文档

1. 概述

TreeMap 是 Java 中的一个集合类,它实现了 SortedMap 接口。它是基于红黑树的数据结构实现的,它能够保持其中的元素处于有序状态。

  • TreeMap 集合中的元素是以键值对的形式存储的,其中的键用于排序和唯一性的保证,而值则用于存储具体的数据。

  • TreeMap 根据键的自然顺序或者自定义的比较器来进行排序,使得在遍历 TreeMap 集合时能够有序地访问其中的元素。

TreeMap 集合的特点

  1. TreeMap 中的键必须是可比较的,要么实现了 Comparable 接口,要么在构造 TreeMap 时提供了自定义的比较器。

  2. TreeMap 中的键是唯一的,不允许重复的键存在。

  3. TreeMap 是基于红黑树实现的,因此在插入、删除和查找操作的时间复杂度均为 O(logn),具有较高的效率。

  4. TreeMap 中的元素是有序的,可以根据键来进行排序。

  5. TreeMap 不是线程安全的,如果需要在多线程环境下使用,需要进行额外的同步处理。

2. 方法

TreeMap集合是Map集合的子类,因此Map集合的方法TreeMap集合都能使用。

Map集合

方法名说明
V put(K key,V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boolean containsKey(Object key)判断集合是否包含指定的键
boolean containsValue(Object value)判断集合是否包含指定的值
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中键值对的个数

3. 遍历方式

与共有的 集合遍历方式 一样

4. 排序方式

TreeMap集合和TreeSet集合一样,底层都是红黑树,因此排序方式一样

TreeSet 集合排序方式详解

  • 默认排序规则/自然排序

  • 比较器排序

5. 代码示例1

  • 代码示例
    需求:键:整数表示id;值:字符串表示商品名称
    要求:按照id的升序排列,按照id的降序排列
package text.text02;
/*TreeMap基本应用:
需求:
    键:整数表示id
    值:字符串表示商品名称
要求:按照id的升序排列,按照id的降序排列
*/

import java.util.Comparator;
import java.util.TreeMap;

public class text52 {
    public static void main(String[] args) {
        //自然排序(升序排列)
        System.out.println("方法一:自然排序");
        method1();        //{1001=平板, 1002=汽车, 1003=手机, 1004=飞机, 1005=电脑}

        //比较器排序(降序排列)
        System.out.println("方法二:比较器排序");
        method2();        //{1005=电脑, 1004=飞机, 1003=手机, 1002=汽车, 1001=平板}
    }

    //自然排序(Java底层默认的自然排序就是按照升序排列)
    public static void method1() {
        //创建集合并添加数据
        TreeMap<Integer, String> tm = new TreeMap<>();
        tm.put(1003, "手机");
        tm.put(1005, "电脑");
        tm.put(1001, "平板");
        tm.put(1002, "汽车");
        tm.put(1004, "飞机");
        System.out.println(tm);
    }

    //比较器排序(当Java底层默认的自然排列不能满足需求时,采用比较器排列)
    public static void method2() {
        //创建集合(在创建对象的时候指定比较器规则)
        TreeMap<Integer, String> tm = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        //添加数据
        tm.put(1003, "手机");
        tm.put(1005, "电脑");
        tm.put(1001, "平板");
        tm.put(1002, "汽车");
        tm.put(1004, "飞机");

        System.out.println(tm);
    }
}

  • 输出结果
    • 方法一:自然排序
      在这里插入图片描述

    • 方法二:比较器排序
      在这里插入图片描述

6. 代码示例2

  • 代码示例
    需求:键:学生对象;值:籍贯
    要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人
package text.text02;

import java.util.*;

/*
需求:
    键:学生对象
    值:籍贯
要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人
 */
public class text53 {
    public static void main(String[] args) {
        //自然排序
        System.out.println("方法一:自然排序");
        method1();
        //比较器排序
        System.out.println("方法二:比较器排序");
        method2();
    }

    //自然排序 (Java底层默认的自然排序就是按照升序排列,自定义对象时,需要在Javabean类中实现Comparable接口并重写里面的CompareTo方法)
    public static void method1() {
        //创建学生对象
        Student8 student1 = new Student8("zhangsan", 10);
        Student8 student2 = new Student8("lisi", 10);
        Student8 student3 = new Student8("wangwu", 11);
        Student8 student4 = new Student8("liubei", 9);
        Student8 student5 = new Student8("guanyu", 13);
        Student8 student6 = new Student8("guanyu", 13);

        //创建集合对象
        TreeMap<Student8, String> tm = new TreeMap<>();

        //添加数据
        tm.put(student1, "陕西");
        tm.put(student2, "湖南");
        tm.put(student3, "河北");
        tm.put(student4, "江苏");
        tm.put(student5, "北京");
        tm.put(student6, "湖南");

        //遍历输出集合
        Set<Map.Entry<Student8, String>> entries = tm.entrySet();
        for (Map.Entry<Student8, String> entry : entries) {
            Student8 key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + " = " + value);
        }
    }

    //比较器排序(当Java底层默认的自然排列不能满足需求时,采用比较器排列,在创建对象时,指定比较规则)
    public static void method2() {
        //创建学生对象
        Student8 student1 = new Student8("zhangsan", 10);
        Student8 student2 = new Student8("lisi", 10);
        Student8 student3 = new Student8("wangwu", 11);
        Student8 student4 = new Student8("liubei", 9);
        Student8 student5 = new Student8("guanyu", 13);
        Student8 student6 = new Student8("guanyu", 13);

        //创建集合对象
        TreeMap<Student8, String> tm = new TreeMap<>(new Comparator<Student8>() {
            @Override
            //按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人
            public int compare(Student8 o1, Student8 o2) {
                //o1:表示当前要添加的元素
                //o2:表示已经在红黑树存在的元素
                //返回值:
                //负数:表示当前要添加的数据是小的,存左边
                //正数:表示当前要添加的数据是大的,存右边
                //0:表示当前要添加的元素已经存在,舍弃
                int i = o1.getAge() - o2.getAge();
                i = i == 0 ? o1.getName().compareTo(o2.getName()) : i;
                return i;
            }
        });

        //添加数据
        tm.put(student1, "陕西");
        tm.put(student2, "湖南");
        tm.put(student3, "河北");
        tm.put(student4, "江苏");
        tm.put(student5, "北京");
        tm.put(student6, "湖南");

        //遍历输出集合
        Set<Map.Entry<Student8, String>> entries = tm.entrySet();
        for (Map.Entry<Student8, String> entry : entries) {
            Student8 key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + " = " + value);
        }
    }
}

//学生对象
class Student8 implements Comparable<Student8> {
    private String name;
    private int age;


    public Student8() {
    }

    public Student8(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     *
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     *
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student8 student8 = (Student8) o;
        return age == student8.age && Objects.equals(name, student8.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public String toString() {
        return "Student8{name = " + name + ", age = " + age + "}";
    }

    @Override
    //按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人
    public int compareTo(Student8 o) {
        //this:表示当前要添加的元素
        //o:表示已经在红黑树中的元素
        //返回值:
        //负数:表示当前要添加的数据是小的,存左边
        //正数:表示当前要添加的数据是大的,存右边
        //0:表示当前要添加的元素已经存在,舍弃
        int i = this.getAge() - o.getAge();
        i = i == 0 ? this.getName().compareTo(o.getName()) : i;
        return i;
    }
}

  • 输出结果
    • 方法一:自然排序
      在这里插入图片描述

    • 方法二:比较器排序
      在这里插入图片描述

7. 代码示例3

  • 代码示例
    统计个数:
    需求:字符串“aababcabcdabcde”,请统计字符串中每一个字符出现的次数,并按照如下格式输出。
    输出结果:a(5)b(4)c(3)d(2)e(1)
package text.text02;

import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeMap;

/*
统计个数:
需求:字符串“aababcabcdabcde”,请统计字符串中每一个字符出现的次数,并按照如下格式输出。
    输出结果:a(5)b(4)c(3)d(2)e(1)

新的统计思想:利用Map集合进行统计      (键:表示要统计的内容;值:表示次数)
    如果题目中没有要求对结果进行排序,默认使用HashMap
    如果题目中要求对结果进行排序,则使用TreeMap

 */
public class text54 {
    public static void main(String[] args) {
        //创建数组存储每一个字符
        char[] arr = {'a', 'b', 'c', 'd', 'e'};

        //定义一个变量用于记录字符串
        String str = "aababcabcdabcde";

        //创建集合
        TreeMap<Character, Integer> tm = new TreeMap<>();

        for (int i = 0; i < str.length(); i++) {
            //如果双列集合中存在该字符,则获取双列集合中该字符的次数并将次数+1
            if (tm.containsKey(str.charAt(i))) {
                //获取双列集合中该字符的次数
                Integer value = tm.get(str.charAt(i));
                //将次数+1
                value++;
                //用新次数覆盖原次数
                tm.put(str.charAt(i), value);
            }
            //如果双列集合中存在该字符,则添加该字符并将次数改为1
            else {
                tm.put(str.charAt(i), 1);
            }
        }
        //遍历集合
        //1.利用StringBuilder修改输出格式
        //创建StringBuilder对象
        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<Character, Integer>> entries = tm.entrySet();
        for (Map.Entry<Character, Integer> entry : entries) {
            //获取集合里的键
            Character key = entry.getKey();
            //获取集合里的值
            Integer value = entry.getValue();
            //将数据按照需求格式添加进StringBuilder集合
            sb.append(key).append("(").append(value).append(")");
        }
        System.out.println("1.利用StringBuilder修改输出格式:");
        System.out.println(sb);                  //a(5)b(4)c(3)d(2)e(1)

        //2.利用StringJoiner修改输出格式
        //创建StringJoiner对象
        StringJoiner sj = new StringJoiner("", "", "");
        Set<Character> set = tm.keySet();
        for (Character key : set) {
            Integer value = tm.get(key);
            //将数据按照需求格式添加进StringJoiner集合
            sj.add(key + "").add("(").add(value + "").add(")");//+" "是为了将key和value转换成字符串
        }
        System.out.println("2.利用StringJoiner修改输出格式:");
        System.out.println(sj);       //a(5)b(4)c(3)d(2)e(1)
    }
}

  • 输出结果
    • 1.利用StringBuilder修改输出格式:
      在这里插入图片描述

    • 2.利用StringJoiner修改输出格式:
      在这里插入图片描述

8. 注意事项

  1. 键的唯一性:TreeMap 中的键是唯一的,不允许重复的键存在。如果尝试插入一个已经存在的键,新的值将会覆盖旧的值。如果需要存储允许重复键的情况,可以考虑使用其他集合类如 ArrayList 或者 HashMap。

  2. 键的可比较性:TreeMap 要求集合中的键必须是可比较的,要么实现了 Comparable 接口,要么在构造 TreeMap 时提供了自定义的比较器。如果键没有实现 Comparable 接口,并且没有提供自定义的比较器,则在插入元素或者进行比较操作时会抛出 ClassCastException 异常。

  3. 线程安全性:TreeMap 不是线程安全的,如果需要在多线程环境下使用 TreeMap,需要进行额外的同步处理。可以考虑使用 Collections 类的 synchronizedSortedMap 方法包装 TreeMap,或者使用并发集合类如 ConcurrentHashMap。

  4. 迭代顺序:TreeMap 中的元素是有序的,可以根据键来进行排序。通过 iterator 或者 forEach 遍历 TreeMap 时,元素会按照键的顺序以升序进行遍历。

  5. 性能开销:由于 TreeMap 的底层是红黑树,插入、删除和查找操作的时间复杂度均为 O(logn),相比于其他集合类可能会有较高的性能开销。如果对性能有较高要求,可以考虑使用其他集合类。

9. 源码分析

  1. TreeMap中每一个节点的内部属性

    K key;					//键
    V value;				//值
    Entry<K,V> left;		//左子节点
    Entry<K,V> right;		//右子节点
    Entry<K,V> parent;		//父节点
    boolean color;			//节点的颜色
    
  2. TreeMap类中中要知道的一些成员变量

    public class TreeMap<K,V>{
       
        //比较器对象
        private final Comparator<? super K> comparator;
    
    	//根节点
        private transient Entry<K,V> root;
    
    	//集合的长度(节点的个数)
        private transient int size = 0;
    
    
  3. 空参构造

    //空参构造就是没有传递比较器对象
    public TreeMap() {
    	comparator = null;
    }
    
  4. 带参构造

    	//带参构造就是传递了比较器对象。
    	public TreeMap(Comparator<? super K> comparator) {
            this.comparator = comparator;
        }
    
  5. 添加元素

    	public V put(K key, V value) {
            return put(key, value, true);
        }
    
    	//参数一:键
    	//参数二:值
    	//参数三:当键重复的时候,是否需要覆盖值
    	//		true:覆盖
    	//		false:不覆盖
    		
    	private V put(K key, V value, boolean replaceOld) {
    		//获取根节点的地址值,赋值给局部变量t
            Entry<K,V> t = root;
    		//判断根节点是否为null
    		//如果为null,表示当前是第一次添加,会把当前要添加的元素,当做根节点
    		//如果不为null,表示当前不是第一次添加,跳过这个判断继续执行下面的代码
            if (t == null) {
    			//方法的底层,会创建一个Entry对象,把他当做根节点
                addEntryToEmptyMap(key, value);
    			//表示此时没有覆盖任何的元素
                return null;
            }
    		//表示两个元素的键比较之后的结果
            int cmp;
    		//表示当前要添加节点的父节点
            Entry<K,V> parent;
    		
    		//表示当前的比较规则
    		//如果我们是采取默认的自然排序,那么此时comparator记录的是null,cpr记录的也是null
    		//如果我们是采取比较器排序方式,那么此时comparator记录的是就是比较器
            Comparator<? super K> cpr = comparator;
    		//表示判断当前是否有比较器对象
    		//如果传递了比较器对象,就执行if里面的代码,此时以比较器的规则为准
    		//如果没有传递比较器对象,就执行else里面的代码,此时以自然排序的规则为准
            if (cpr != null) {
                do {
                    parent = t;
                    cmp = cpr.compare(key, t.key);
                    if (cmp < 0)
                        t = t.left;
                    else if (cmp > 0)
                        t = t.right;
                    else {
                        V oldValue = t.value;
                        if (replaceOld || oldValue == null) {
                            t.value = value;
                        }
                        return oldValue;
                    }
                } while (t != null);
            } else {
    			//把键进行强转,强转成Comparable类型的
    			//要求:键必须要实现Comparable接口,如果没有实现这个接口
    			//此时在强转的时候,就会报错。
                Comparable<? super K> k = (Comparable<? super K>) key;
                do {
    				//把根节点当做当前节点的父节点
                    parent = t;
    				//调用compareTo方法,比较根节点和当前要添加节点的大小关系
                    cmp = k.compareTo(t.key);
    				
                    if (cmp < 0)
    					//如果比较的结果为负数
    					//那么继续到根节点的左边去找
                        t = t.left;
                    else if (cmp > 0)
    					//如果比较的结果为正数
    					//那么继续到根节点的右边去找
                        t = t.right;
                    else {
    					//如果比较的结果为0,会覆盖
                        V oldValue = t.value;
                        if (replaceOld || oldValue == null) {
                            t.value = value;
                        }
                        return oldValue;
                    }
                } while (t != null);
            }
    		//就会把当前节点按照指定的规则进行添加
            addEntry(key, value, parent, cmp < 0);
            return null;
        }	
    	
    	
    	
    	 private void addEntry(K key, V value, Entry<K, V> parent, boolean addToLeft) {
            Entry<K,V> e = new Entry<>(key, value, parent);
            if (addToLeft)
                parent.left = e;
            else
                parent.right = e;
    		//添加完毕之后,需要按照红黑树的规则进行调整
            fixAfterInsertion(e);
            size++;
            modCount++;
        }
    	
    	
    	
    	private void fixAfterInsertion(Entry<K,V> x) {
    		//因为红黑树的节点默认就是红色的
            x.color = RED;
    
    		//按照红黑规则进行调整
    		
    		//parentOf:获取x的父节点
    		//parentOf(parentOf(x)):获取x的爷爷节点
    		//leftOf:获取左子节点
            while (x != null && x != root && x.parent.color == RED) {
    			
    			
    			//判断当前节点的父节点是爷爷节点的左子节点还是右子节点
    			//目的:为了获取当前节点的叔叔节点
                if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
    				//表示当前节点的父节点是爷爷节点的左子节点
    				//那么下面就可以用rightOf获取到当前节点的叔叔节点
                    Entry<K,V> y = rightOf(parentOf(parentOf(x)));
                    if (colorOf(y) == RED) {
    					//叔叔节点为红色的处理方案
    					
    					//把父节点设置为黑色
                        setColor(parentOf(x), BLACK);
    					//把叔叔节点设置为黑色
                        setColor(y, BLACK);
    					//把爷爷节点设置为红色
                        setColor(parentOf(parentOf(x)), RED);
    					
    					//把爷爷节点设置为当前节点
                        x = parentOf(parentOf(x));
                    } else {
    					
    					//叔叔节点为黑色的处理方案
    					
    					
    					//表示判断当前节点是否为父节点的右子节点
                        if (x == rightOf(parentOf(x))) {
    						
    						//表示当前节点是父节点的右子节点
                            x = parentOf(x);
    						//左旋
                            rotateLeft(x);
                        }
                        setColor(parentOf(x), BLACK);
                        setColor(parentOf(parentOf(x)), RED);
                        rotateRight(parentOf(parentOf(x)));
                    }
                } else {
    				//表示当前节点的父节点是爷爷节点的右子节点
    				//那么下面就可以用leftOf获取到当前节点的叔叔节点
                    Entry<K,V> y = leftOf(parentOf(parentOf(x)));
                    if (colorOf(y) == RED) {
                        setColor(parentOf(x), BLACK);
                        setColor(y, BLACK);
                        setColor(parentOf(parentOf(x)), RED);
                        x = parentOf(parentOf(x));
                    } else {
                        if (x == leftOf(parentOf(x))) {
                            x = parentOf(x);
                            rotateRight(x);
                        }
                        setColor(parentOf(x), BLACK);
                        setColor(parentOf(parentOf(x)), RED);
                        rotateLeft(parentOf(parentOf(x)));
                    }
                }
            }
    		
    		//把根节点设置为黑色
            root.color = BLACK;
        }
    
  6. 课堂思考问题:

    1. TreeMap添加元素的时候,键是否需要重写hashCode和equals方法?

    此时是不需要重写的。

    1. HashMap是哈希表结构的,JDK8开始由数组,链表,红黑树组成的。
      既然有红黑树,HashMap的键是否需要实现Compareable接口或者传递比较器对象呢?

    不需要的。
    因为在HashMap的底层,默认是利用哈希值的大小关系来创建红黑树的

    1. TreeMap和HashMap谁的效率更高?

    如果是最坏情况,添加了8个元素,这8个元素形成了链表,此时TreeMap的效率要更高
    但是这种情况出现的几率非常的少。
    一般而言,还是HashMap的效率要更高。

    1. 你觉得在Map集合中,java会提供一个如果键重复了,不会覆盖的put方法呢?

    此时putIfAbsent本身不重要。

    传递一个思想:
    代码中的逻辑都有两面性,如果我们只知道了其中的A面,而且代码中还发现了有变量可以控制两面性的发生。
    那么该逻辑一定会有B面。

     习惯:
     boolean类型的变量控制,一般只有AB两面,因为boolean只有两个值
     int类型的变量控制,一般至少有三面,因为int可以取多个值。	
    
    1. 三种双列集合,以后如何选择?
      HashMap LinkedHashMap TreeMap

    默认:HashMap(效率最高)
    如果要保证存取有序:LinkedHashMap
    如果要进行排序:TreeMap

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

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

相关文章

【网工】华为设备命令学习(服务器发布)

本次实验主要是内网静态nat配置没&#xff0c;对外地址可以理解为一台内网的服务器&#xff0c;外网设备可以ping通内网的服务器设备&#xff0c;但是ping不通内网的IP。 除了AR1设备配置有区别&#xff0c;其他设备都是基础IP的配置。 [Huawei]int g0/0/0 [Huawei-GigabitEt…

5.1 灯光色彩与视觉

5.1 灯光色彩与视觉 视觉成像 灯光与物体的反应:吸收,反射和折射 色彩:光照到物体上,物体吸收其他光源色,只反射该颜色光,所以物体 表面呈现该颜色 视觉:该颜色光进入人眼刺激感光细胞,并在视网膜上形成影像. ABSORBTION 一、基础灯光 1.环境光&#xff08;Ambient Light…

Python小白:Python 编辑器那么多种,到底怎么选!!

前言 我在刚刚接触编程的时候很纠结于这个问题&#xff0c;因为我想找一个功能强大&#xff0c;免费&#xff0c;可多平台&#xff0c;支持多种语言的编辑器&#xff0c;所以我特意花费了一些时间对 Python 的编辑器进行了调研&#xff0c;我最终选择了 VScode 作为我的首选编…

GEE详细教程之:将Landsat8与Landsat9影像合成一个影像

1.前言 因项目需求&#xff0c;需要获取一个研究区的Landsat8影像&#xff0c;但Landsat8重复周期长&#xff0c;加之天气的影响&#xff0c;很难获取影像质量较好的影像。Landsat4/5/7的波段顺序与landsat8不同&#xff0c;除此之外&#xff0c;landsat7影像还需要工具进行条带…

《MySQL 简易速速上手小册》第6章:MySQL 复制和分布式数据库(2024 最新版)

文章目录 6.1 设置和管理复制6.1.1 基础知识6.1.2 重点案例&#xff1a;使用 Python 设置 MySQL 主从复制6.1.3 拓展案例 1&#xff1a;自动故障转移6.1.4 拓展案例 2&#xff1a;设置双主复制 6.2 复制的类型和策略6.2.1 基础知识6.2.2 重点案例&#xff1a;使用 Python 设置半…

保育员答案在哪搜?这4款足够解决问题 #媒体#其他#其他

学会运用各类学习辅助工具和资料&#xff0c;是大学生培养自主学习能力和信息获取能力的重要途径之一。 1.石墨文档 石墨文档(Shimo Docs)是一款强大的在线文档协作工具。它提供了多人实时协作、版本控制、评论和批注等功能&#xff0c;方便学生在学习中进行文档编写、合作项…

【芯片设计- RTL 数字逻辑设计入门 14 -- 使用子模块实现三输入数的大小比较】

文章目录 三输入数的大小比较问题分析verilog codeTestBench Code综合图仿真波形图 三输入数的大小比较 在数字芯片设计中&#xff0c;通常把完成特定功能且相对独立的代码编写成子模块&#xff0c;在需要的时候再在主模块中例化使用&#xff0c;以提高代码的可复用性和设计的层…

【网工】华为设备命令学习(Telnet)

本次实验AR3为我们实际中远程的路由&#xff0c;AR4模拟我们的设备&#xff0c;最终实现Telnet的远程控制路由&#xff01; 本次笔记主要记录Telnet技术实现原理&#xff0c;后续再补充具体配置代码。 Telnet协议是TCP/IP协议族中的一员&#xff0c;是Internet远程登录服务的…

Huggingface上传模型

Huggingface上传自己的模型 参考 https://juejin.cn/post/7081452948550746148https://huggingface.co/blog/password-git-deprecationAdding your model to the Hugging Face Hub&#xff0c; huggingface.co/docs/hub/ad…Welcome&#xff0c;huggingface.co/welcome三句指…

猫头虎分享已解决Bug || CPU过载(CPU Overload):HighCpuUsageWarning, CpuOverloadException

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

基础图算法与社交网络分析

目录 前言1 寻找最短路径的Dijkstra算法1.1 介绍1.2 算法步骤1.3 应用领域1.4 算法优势与限制 2 构建高效网络结构的最小生成树算法2.1 Kruskal算法2.2 应用领域2.3 算法优势与限制 3 中心度算法3.1 PageRank算法3.2 Degree Centrality&#xff08;度中心度&#xff09;3.3 Bet…

Web 目录爆破神器:DirBuster 保姆级教程(附链接)

一、介绍 DirBuster 是一个用于强制目录浏览的渗透测试工具&#xff0c;它主要用于在Web应用程序中识别隐藏的目录和文件。这个工具被设计成非常灵活&#xff0c;可以根据用户的需求进行配置。以下是 DirBuster 的一些主要特点和用法&#xff1a; 主要特点&#xff1a; 字典爆…

Python入门:常用模块—os模块及sys模块

os模块 sys模块 import sys print(sys.argv) # 命令参数list&#xff0c;第一个元素是程序本身路径 print(sys.exit()) # 退出程序&#xff0c;正常退出是exit(0) print(sys.version) # 获取python解释程序的版本信息 print(sys.maxint()) # 最大…

【网络技术】【Kali Linux】Nmap嗅探(二)多设备扫描

上期实验博文&#xff1a;&#xff08;一&#xff09;简单扫描 一、实验环境 本次实验进行Nmap多设备扫描&#xff0c;实验使用 Kali Linux 虚拟机&#xff08;扫描端&#xff09;、Ubuntu 22.04虚拟机&#xff08;被扫描端1&#xff09;、Ubuntu 18.04虚拟机&#xff08;被扫…

微信红包测试用例设计,龙年大吉!

前言 大家好&#xff0c;我是chowley&#xff0c;在这里祝大家龙年大吉&#xff0c;身体健康&#xff0c;这次来回忆一下当时参加腾讯技术面的场景题&#xff0c;面试官让我测试拼手气红包&#xff0c;不需要考虑其他方面&#xff0c;只在功能方面进行探索。 我先贴一张红包界…

Redis核心技术与实战【学习笔记】 - 26.Redis数分布优化(应对数据倾斜问题)

简述 在切片集群中&#xff0c;数据会按照一定的规则分散到不同的实例上保存。比如&#xff0c;Redis Cluster 或 Codis 会先按照 CRC 算法的计算值对 Slot&#xff08;逻辑槽&#xff09;取模&#xff0c;同时 Slot 又有运维管理员分配到不同的实例上。这样&#xff0c;数据就…

大模型|基础_word2vec

文章目录 Word2Vec词袋模型CBOW Continuous Bag-of-WordsContinuous Skip-Gram存在的问题解决方案 其他技巧 Word2Vec 将词转化为向量后&#xff0c;会发现king和queen的差别与man和woman的差别是类似的&#xff0c;而在几何空间上&#xff0c;这样的差别将会以平行的关系进行表…

基于深度学习算法的轴承故障自主分类

1. 要求 轴承有3种故障&#xff1a;外圈故障&#xff0c;内圈故障&#xff0c;滚珠故障&#xff0c;外加正常的工作状态。如表1所示&#xff0c;结合轴承的3种直径&#xff08;直径1,直径2,直径3&#xff09;&#xff0c;轴承的工作状态有10类&#xff1a; 表1 轴承故障类别 外…

横扫Spark之 - 9个常见的行动算子

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 1. collect()2. count()3. first()4. take()5. takeOrdered()6. countByKey()7. saveAS...()8. foreach()9. foreachPartition() *** 1. collect() 收集RDD每个分区的数据以数组封装之后发…

【FFmpeg】ffplay 命令行参数 ⑤ ( 设置音频滤镜 -af 参数 | 设置统计信息 -stats 参数 | 设置同步时钟类型 -sync 参数 )

文章目录 一、ffplay 命令行参数 - 音频滤镜1、设置音频滤镜 -af 参数2、常用的 音频滤镜 参数3、音频滤镜链 示例 二、ffplay 命令行参数 - 统计信息1、设置统计信息 -stats 参数2、关闭统计信息 -nostats 参数 三、ffplay 命令行参数 - 同步时钟类型1、设置同步时钟类型 -syn…