十二、集合(2)

news2024/11/17 11:36:36

本章概要

  • 添加元素组
  • 集合的打印
  • 列表 List

添加元素组

java.util 包中的 ArraysCollections 类中都有很多实用的方法,可以在一个 Collection 中添加一组元素。

Arrays.asList() 方法接受一个数组或是逗号分隔的元素列表(使用可变参数),并将其转换为 List 对象。 Collections.addAll() 方法接受一个 Collection 对象,以及一个数组或是一个逗号分隔的列表,将其中元素添加到 Collection 中。下边的示例展示了这两个方法,以及更通用的 、所有 Collection 类型都包含的addAll() 方法:

// collections/AddingGroups.java
// Adding groups of elements to Collection objects
import java.util.*;

public class AddingGroups {
    public static void main(String[] args) {
        Collection<Integer> collection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
        Integer[] moreInts = {6, 7, 8, 9, 10};
        collection.addAll(Arrays.asList(moreInts));
        // Runs significantly faster, but you can't
        // construct a Collection this way:
        Collections.addAll(collection, 11, 12, 13, 14, 15);
        Collections.addAll(collection, moreInts);
        // Produces a list "backed by" an array:
        List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);
        list.set(1, 99); // OK -- modify an element
        // list.add(21); // Runtime error; the underlying
        // array cannot be resized.
    }
}

Collection 的构造器可以接受另一个 Collection,用它来将自身初始化。因此,可以使用 Arrays.asList() 来为这个构造器产生输入。但是, Collections.addAll() 运行得更快,而且很容易构建一个不包含元素的 Collection ,然后调用 Collections.addAll() ,因此这是首选方式。

Collection.addAll() 方法只能接受另一个 Collection 作为参数,因此它没有 Arrays.asList()Collections.addAll() 灵活。这两个方法都使用可变参数列表。

也可以直接使用 Arrays.asList() 的输出作为一个 List ,但是这里的底层实现是数组,没法调整大小。如果尝试在这个 List 上调用 add()remove(),由于这两个方法会尝试修改数组大小,所以会在运行时得到“Unsupported Operation(不支持的操作)”错误:

// collections/AsListInference.java
import java.util.*;

class Snow {
}

class Powder extends Snow {
}

class Light extends Powder {
}

class Heavy extends Powder {
}

class Crusty extends Snow {
}

class Slush extends Snow {
}

public class AsListInference {
    public static void main(String[] args) {
        List<Snow> snow1 = Arrays.asList(new Crusty(), new Slush(), new Powder());
        //- snow1.add(new Heavy()); // Exception

        List<Snow> snow2 = Arrays.asList(new Light(), new Heavy());
        //- snow2.add(new Slush()); // Exception

        List<Snow> snow3 = new ArrayList<>();
        Collections.addAll(snow3,new Light(), new Heavy(), new Powder());
        snow3.add(new Crusty());

        // Hint with explicit type argument specification:
        List<Snow> snow4 = Arrays.<Snow>asList(new Light(), new Heavy(), new Slush());
        //- snow4.add(new Powder()); // Exception
    }
}

snow4 中,注意 Arrays.asList() 中间的“暗示”(即 <Snow> ),告诉编译器 Arrays.asList() 生成的结果 List 类型的实际目标类型是什么。这称为_显式类型参数说明_(explicit type argument specification)。

集合的打印

必须使用 Arrays.toString() 来生成数组的可打印形式。但是打印集合无需任何帮助。下面是一个例子,这个例子中也介绍了基本的Java集合:

// collections/PrintingCollections.java
// Collections print themselves automatically
import java.util.*;

public class PrintingCollections {
    static Collection fill(Collection<String> collection) {
        collection.add("rat");
        collection.add("cat");
        collection.add("dog");
        collection.add("dog");
        return collection;
    }

    static Map fill(Map<String, String> map) {
        map.put("rat", "Fuzzy");
        map.put("cat", "Rags");
        map.put("dog", "Bosco");
        map.put("dog", "Spot");
        return map;
    }

    public static void main(String[] args) {
        System.out.println(fill(new ArrayList<>()));
        System.out.println(fill(new LinkedList<>()));
        System.out.println(fill(new HashSet<>()));
        System.out.println(fill(new TreeSet<>()));
        System.out.println(fill(new LinkedHashSet<>()));
        System.out.println(fill(new HashMap<>()));
        System.out.println(fill(new TreeMap<>()));
        System.out.println(fill(new LinkedHashMap<>()));
    }
}

在这里插入图片描述

这显示了Java集合库中的两个主要类型。它们的区别在于集合中的每个“槽”(slot)保存的元素个数。 Collection 类型在每个槽中只能保存一个元素。此类集合包括: List ,它以特定的顺序保存一组元素; Set ,其中元素不允许重复; Queue ,只能在集合一端插入对象,并从另一端移除对象(就本例而言,这只是查看序列的另一种方式,因此并没有显示它)。 Map 在每个槽中存放了两个元素,即_键_ (key)和与之关联的_值_ (value)。

默认的打印行为,使用集合提供的 toString() 方法即可生成可读性很好的结果。 Collection 打印出的内容用方括号括住,每个元素由逗号分隔。 Map 则由大括号括住,每个键和值用等号连接(键在左侧,值在右侧)。

第一个 fill() 方法适用于所有类型的 Collection ,这些类型都实现了 add() 方法以添加新元素。

ArrayListLinkedList 都是 List 的类型,从输出中可以看出,它们都按插入顺序保存元素。两者之间的区别不仅在于执行某些类型的操作时的性能,而且 LinkedList 包含的操作多于 ArrayList 。本章后面将对这些内容进行更全面的探讨。

HashSetTreeSetLinkedHashSetSet 的类型。从输出中可以看到, Set 仅保存每个相同项中的一个,并且不同的 Set 实现存储元素的方式也不同。 HashSet 使用相当复杂的方法存储元素,现在只需要知道,这种技术是检索元素的最快方法,因此,存储顺序看上去没有什么意义(通常只关心某事物是否是 Set 的成员,而存储顺序并不重要)。如果存储顺序很重要,则可以使用 TreeSet ,它把对象按照比较规则来排序;还有 LinkedHashSet ,它把对象按照被添加的先后顺序来排序。

Map (也称为_关联数组_)使用_键_来查找对象,就像一个简单的数据库。所关联的对象称为_值_。 假设有一个 Map 将美国州名与它们的首府联系在一起,如果想要俄亥俄州(Ohio)的首府,可以用“Ohio”作为键来查找,几乎就像使用数组下标一样。正是由于这种行为,对于每个键, Map 只存储一次。

Map.put(key, value) 添加一个所想要添加的值并将它与一个键(用来查找值)相关联。 Map.get(key) 生成与该键相关联的值。上面的示例仅添加键值对,并没有执行查找。这将在稍后展示。

请注意,这里没有指定(或考虑) Map 的大小,因为它会自动调整大小。 此外, Map 还知道如何打印自己,它会显示相关联的键和值。

本例使用了 Map 的三种基本风格: HashMapTreeMapLinkedHashMap

键和值保存在 HashMap 中的顺序不是插入顺序,因为 HashMap 实现使用了非常快速的算法来控制顺序。 TreeMap 把所有的键按照比较规则来排序, LinkedHashMap 在保持 HashMap 查找速度的同时按照键的插入顺序来排序。

列表List

List承诺将元素保存在特定的序列中。 List 接口在 Collection 的基础上添加了许多方法,允许在 List 的中间插入和删除元素。

有两种类型的 List

  • 基本的 ArrayList ,擅长随机访问元素,但在 List 中间插入和删除元素时速度较慢。
  • LinkedList ,它通过代价较低的在 List 中间进行的插入和删除操作,提供了优化的顺序访问。 LinkedList 对于随机访问来说相对较慢,但它具有比 ArrayList 更大的特征集。

下面的示例导入 typeinfo.pets ,超前使用了类型信息一章中的类库。这个类库包含了 Pet 类层次结构,以及用于随机生成 Pet 对象的一些工具类。此时不需要了解完整的详细信息,只需要知道两点:

  1. 有一个 Pet 类,以及 Pet 的各种子类型。
  2. 静态的 new PetCreator().list() 方法返回一个填充了随机选取的 Pet 对象的 ArrayList

ListFeatures.java

import java.util.*;

public class ListFeatures {
    public static void main(String[] args) {
        Random rand = new Random(47);
        List<Pet> pets = new PetCreator().list(7);
        System.out.println("1: " + pets);
        Hamster h = new Hamster();
        pets.add(h); // Automatically resizes
        System.out.println("2: " + pets);
        System.out.println("3: " + pets.contains(h));
        pets.remove(h); // Remove by object
        Pet p = pets.get(2);
        System.out.println("4: " + p + " " + pets.indexOf(p));
        Pet cymric = new Cymric();
        System.out.println("5: " + pets.indexOf(cymric));
        System.out.println("6: " + pets.remove(cymric));
        // Must be the exact object:
        System.out.println("7: " + pets.remove(p));
        System.out.println("8: " + pets);
        pets.add(3, new Mouse()); // Insert at an index
        System.out.println("9: " + pets);
        List<Pet> sub = pets.subList(1, 4);
        System.out.println("subList: " + sub);
        System.out.println("10: " + pets.containsAll(sub));
        Collections.sort(sub); // In-place sort
        System.out.println("sorted subList: " + sub);
        // Order is not important in containsAll():
        System.out.println("11: " + pets.containsAll(sub));
        Collections.shuffle(sub, rand); // Mix it up
        System.out.println("shuffled subList: " + sub);
        System.out.println("12: " + pets.containsAll(sub));
        List<Pet> copy = new ArrayList<>(pets);
        sub = Arrays.asList(pets.get(1), pets.get(4));
        System.out.println("sub: " + sub);
        copy.retainAll(sub);
        System.out.println("13: " + copy);
        copy = new ArrayList<>(pets); // Get a fresh copy
        copy.remove(2); // Remove by index
        System.out.println("14: " + copy);
        copy.removeAll(sub); // Only removes exact objects
        System.out.println("15: " + copy);
        copy.set(1, new Mouse()); // Replace an element
        System.out.println("16: " + copy);
        copy.addAll(2, sub); // Insert a list in the middle
        System.out.println("17: " + copy);
        System.out.println("18: " + pets.isEmpty());
        pets.clear(); // Remove all elements
        System.out.println("19: " + pets);
        System.out.println("20: " + pets.isEmpty());
        pets.addAll(new PetCreator().list(4));
        System.out.println("21: " + pets);
        Object[] o = pets.toArray();
        System.out.println("22: " + o[3]);
        Pet[] pa = pets.toArray(new Pet[0]);
        System.out.println("23: " + pa[3].id());
    }
}

其它相关类:

Cat.java

public class Cat extends Pet {
  public Cat(String name) { super(name); }
  public Cat() { super(); }
}

Creator.java

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public abstract class Creator implements Supplier<Pet> {
    private Random rand = new Random(47);

    // The different types of Pet to create:
    public abstract List<Class<? extends Pet>> types();

    @Override
    public Pet get() { // Create one random Pet
        int n = rand.nextInt(types().size());
        try {
            return types().get(n)
                    .getConstructor().newInstance();
        } catch (InstantiationException |
                 NoSuchMethodException |
                 InvocationTargetException |
                 IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public Stream<Pet> stream() {
        return Stream.generate(this);
    }

    public Pet[] array(int size) {
        return stream().limit(size).toArray(Pet[]::new);
    }

    public List<Pet> list(int size) {
        return stream().limit(size).collect(Collectors.toCollection(ArrayList::new));
    }
}

Cymric.java

public class Cymric extends Manx {
  public Cymric(String name) { super(name); }
  public Cymric() { super(); }
}

Dog.java

public class Dog extends Pet {
  public Dog(String name) { super(name); }
  public Dog() { super(); }
}

EgyptianMau.java

public class EgyptianMau extends Cat {
  public EgyptianMau(String name) { super(name); }
  public EgyptianMau() { super(); }
}

Hamster.java

public class Hamster extends Rodent {
  public Hamster(String name) { super(name); }
  public Hamster() { super(); }
}

Individual.java

import java.util.Objects;

public class Individual implements Comparable<Individual> {
    private static long counter = 0;
    private final long id = counter++;
    private String name;

    public Individual(String name) {
        this.name = name;
    }

    // 'name' is optional:
    public Individual() {
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() +
                (name == null ? "" : " " + name);
    }

    public long id() {
        return id;
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof Individual &&
                Objects.equals(id, ((Individual) o).id);
    }

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

    @Override
    public int compareTo(Individual arg) {
        // Compare by class name first:
        String first = getClass().getSimpleName();
        String argFirst = arg.getClass().getSimpleName();
        int firstCompare = first.compareTo(argFirst);
        if (firstCompare != 0) {
            return firstCompare;
        }
        if (name != null && arg.name != null) {
            int secondCompare = name.compareTo(arg.name);
            if (secondCompare != 0) {
                return secondCompare;
            }
        }
        return (arg.id < id ? -1 : (arg.id == id ? 0 : 1));
    }
}

Manx.java

public class Manx extends Cat {
  public Manx(String name) { super(name); }
  public Manx() { super(); }
}

Mouse.java

public class Mouse extends Rodent {
  public Mouse(String name) { super(name); }
  public Mouse() { super(); }
}

Mutt.java

public class Mutt extends Dog {
  public Mutt(String name) { super(name); }
  public Mutt() { super(); }
}

Pet.java

public class Pet extends Individual {
    public Pet(String name) {
        super(name);
    }

    public Pet() {
        super();
    }
}

PetCreator.java

import java.util.*;

public class PetCreator extends Creator {
    // No try block needed.
    public static final
    List<Class<? extends Pet>> ALL_TYPES = Collections.unmodifiableList(Arrays.asList(
                    Pet.class, Dog.class, Cat.class, Rodent.class,
                    Mutt.class, Pug.class, EgyptianMau.class,
                    Manx.class, Cymric.class, Rat.class,
                    Mouse.class, Hamster.class));
    // Types for random creation:
    private static final
    List<Class<? extends Pet>> TYPES =
            ALL_TYPES.subList(
                    ALL_TYPES.indexOf(Mutt.class),
                    ALL_TYPES.size());

    @Override
    public List<Class<? extends Pet>> types() {
        return TYPES;
    }

    public static void main(String[] args) {
        System.out.println(TYPES);
        List<Pet> pets = new PetCreator().list(7);
        System.out.println(pets);
    }
}
/* Output:
[class reflection.pets.Mutt, class reflection.pets.Pug,
class reflection.pets.EgyptianMau, class
reflection.pets.Manx, class reflection.pets.Cymric, class
reflection.pets.Rat, class reflection.pets.Mouse, class
reflection.pets.Hamster]
[Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug]
*/

Pug.java

public class Pug extends Dog {
  public Pug(String name) { super(name); }
  public Pug() { super(); }
}

Rat.java

public class Rat extends Rodent {
  public Rat(String name) { super(name); }
  public Rat() { super(); }
}

Rodent.java

public class Rodent extends Pet {
  public Rodent(String name) { super(name); }
  public Rodent() { super(); }
}

打印内容如下:

在这里插入图片描述

打印行都编了号,因此可从输出追溯到源代码。 第 1 行输出展示了原始的由 Pet 组成的 List 。 与数组不同, List 可以在创建后添加或删除元素,并自行调整大小。这正是它的重要价值:一种可修改的序列。在第 2 行输出中可以看到添加一个 Hamster 的结果,该对象将被追加到列表的末尾。

可以使用 contains() 方法确定对象是否在列表中。如果要删除一个对象,可以将该对象的引用传递给 remove() 方法。同样,如果有一个对象的引用,可以使用 indexOf()List 中找到该对象所在位置的下标号,如第 4 行输出所示中所示。

当确定元素是否是属于某个 List ,寻找某个元素的索引,以及通过引用从 List 中删除元素时,都会用到 equals() 方法(根类 Object 的一个方法)。每个 Pet 被定义为一个唯一的对象,所以即使列表中已经有两个 Cymrics ,如果再创建一个新的 Cymric 对象并将其传递给 indexOf() 方法,结果仍为 -1 (表示未找到),并且尝试调用 remove() 方法来删除这个对象将返回 false 。对于其他类, equals() 的定义可能有所不同。例如,如果两个 String 的内容相同,则这两个 String 相等。因此,为了防止出现意外,请务必注意 List 行为会根据 equals() 行为而发生变化。

第 7、8 行输出展示了删除与 List 中的对象完全匹配的对象是成功的。

可以在 List 的中间插入一个元素,就像在第 9 行输出和它之前的代码那样。但这会带来一个问题:对于 LinkedList ,在列表中间插入和删除都是廉价操作(在本例中,除了对列表中间进行的真正的随机访问),但对于 ArrayList ,这可是代价高昂的操作。这是否意味着永远不应该在 ArrayList 的中间插入元素,并最好是转换为 LinkedList ?不,它只是意味着你应该意识到这个问题,如果你开始在某个 ArrayList 中间执行很多插入操作,并且程序开始变慢,那么你应该看看你的 List 实现有可能就是罪魁祸首(发现此类瓶颈的最佳方式是使用分析器 profiler)。优化是一个很棘手的问题,最好的策略就是置之不顾,直到发现必须要去担心它了(尽管去理解这些问题总是一个很好的主意)。

subList() 方法可以轻松地从更大的列表中创建切片,当将切片结果传递给原来这个较大的列表的 containsAll() 方法时,很自然地会得到 true。请注意,顺序并不重要,在第 11、12 行输出中可以看到,在 sub 上调用直观命名的 Collections.sort()Collections.shuffle() 方法,不会影响 containsAll() 的结果。 subList() 所产生的列表的幕后支持就是原始列表。因此,对所返回列表的更改都将会反映在原始列表中,反之亦然。

retainAll() 方法实际上是一个“集合交集”操作,在本例中,它保留了同时在 copysub 中的所有元素。请再次注意,所产生的结果行为依赖于 equals() 方法。

第 14 行输出展示了使用索引号来删除元素的结果,与通过对象引用来删除元素相比,它显得更加直观,因为在使用索引时,不必担心 equals() 的行为。

removeAll() 方法也是基于 equals() 方法运行的。 顾名思义,它会从 List 中删除在参数 List 中的所有元素。

set() 方法的命名显得很不合时宜,因为它与 Set 类存在潜在的冲突。在这里使用“replace”可能更适合,因为它的功能是用第二个参数替换索引处的元素(第一个参数)。

第 17 行输出表明,对于 List ,有一个重载的 addAll() 方法可以将新列表插入到原始列表的中间位置,而不是仅能用 CollectionaddAll() 方法将其追加到列表的末尾。

第 18 - 20 行输出展示了 isEmpty()clear() 方法的效果。

第 22、23 行输出展示了如何使用 toArray() 方法将任意的 Collection 转换为数组。这是一个重载方法,其无参版本返回一个 Object 数组,但是如果将目标类型的数组传递给这个重载版本,那么它会生成一个指定类型的数组(假设它通过了类型检查)。如果参数数组太小而无法容纳 List 中的所有元素(就像本例一样),则 toArray() 会创建一个具有合适尺寸的新数组。 Pet 对象有一个 id() 方法,可以在所产生的数组中的对象上调用这个方法。

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

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

相关文章

8.react18并发模式与startTransition(搜索高亮思路)

React 18 之前,渲染是一个单一的,不间断的,同步的事务,一旦渲染开始,就不能被中断 React 18引入并发模式,它允许你将标记更新作为一个transitions,这会告诉React他们可以被中断执行.这样可以将紧急任务先更新,不紧急任务后更新. 将任务给紧急任务先执行, 优先级低的任务后执行…

avue实现用户本地保存自定义配置字段属性及注意事项

avue实现用户本地保存自定义配置字段属性及注意事项 先看一段基于vue-nuxt2的page代码&#xff1a; 代码文件AvueSaveOption.vue <template><div><p>用户保存自定义表格项</p><avue-crudref"crud":defaults.sync"defaults":opt…

华为云服务器前后端分离项目打包上传及nginx配置

目录 1、Spring Boot项目打包 2、后端上传到云服务器 3、前端打包 1&#xff09;前端请求路径修改 2&#xff09;打包上传 4、下载nginx 1&#xff09;添加源 2&#xff09;安装Nginx 3&#xff09;查看nginx安装目录和版本 4&#xff09;启动 重启nginx命令 5&#…

接口测试与功能测试的区别~

今天为大家分享的是我们在日常测试工作中, 一定会接触并且目前在企业中是主要测试内容的 功能测试与接口测试 一.功能测试与接口测试的基本概念。 1.1 什么是功能测试呢? 功能测试: 是黑盒测试的一方面, 检查实际软件的功能是否符合用户的需求 功能测试测试的内容包括以下…

工程制造领域:企业IT架构

一、500强IT部门的组织规划架构图 1.1 IT服务保证梯队与指导思想 二、工程制造领域&#xff0c;整体业务规划架构图 三、工程制造领域&#xff0c;数据化项目规划架构图 四、工程制造领域&#xff0c;IT应用系统集成架构图

15. 实现业务功能--帖子操作

1. 集成编译器 editor.md 支持 MarkDown 语法编辑&#xff0c;在需要用户输⼊内容的页面按以下代码嵌入编辑器 1.1 编写 HTML <!-- 引⼊编辑器的CSS --> <link rel"stylesheet" href"./dist/editor.md/css/editormd.min.css"> <!-- 引⼊编…

学习pytorch6 torchvision中的数据集使用

torchvision中的数据集使用 1. torchvision中的数据集使用官网文档注意点1 totensor实例化不要忘记加括号注意点2 download可以一直保持为True代码执行结果 2. DataLoader的使用 1. torchvision中的数据集使用 官网文档 注意左上角的版本 https://pytorch.org/vision/0.9/ 注…

行业趋势和新兴领域分析:分析当前网络安全行业的发展趋势,如IoT安全、AI安全、区块链安全等。

第一章&#xff1a;引言 随着数字化时代的迅速发展&#xff0c;网络安全已经成为各行各业不可忽视的重要领域。恶意攻击、数据泄露以及黑客入侵等威胁逐渐增多&#xff0c;推动着网络安全行业不断创新与进步。本文将深入探讨当前网络安全领域的发展趋势&#xff0c;聚焦于新兴…

肿瘤科医师狂喜,15分RNA修饰数据挖掘文章

Biomamba荐语 与这个系列的前面一些论文类似&#xff0c;这次给大家推荐的是一篇纯生物信息学数据挖掘的文章&#xff0c;换句话说&#xff0c;这又是一篇不需要支出科研经费&#xff08;白嫖&#xff09;的论文(当然&#xff0c;生信分析用的服务器还是得掏点费用的)。一般来…

springboot第37集:kafka,mqtt,Netty,nginx,CentOS,Webpack

image.png binzookeeper-server-start.shconfigzookeeper.properties.png image.png image.png 消费 image.png image.png image.png image.png image.png image.png image.png image.png image.png Netty的优点有很多&#xff1a; API使用简单&#xff0c;学习成本低。功能强大…

【操作系统】聊聊文件传输的零拷贝、PageCache、异步IO机制

在目前主流的系统中&#xff0c;其实大多数都是数据密集型系统&#xff0c;所以设计数据密集型应用一书非常经典&#xff0c;推荐一读。而大多数遇到的问题都是存储问题。CPU、内存 因为本身的读写速度比较快&#xff0c;所以磁盘就成为了一个性能瓶颈。 针对磁盘优化的技术层…

对class文件进行base64编码

使用以下代码 package org.springframework.cloud.gateway.sample;import org.springframework.util.Base64Utils;import java.io.*; import java.nio.charset.StandardCharsets;public class EncodeShell {public static void main(String[] args){byte[] data null;try {In…

大数据之linux入门

一、linux是什么 linux操作系统 开发者是林纳斯-托瓦兹&#xff0c;出于个人爱好编写。linux是一个基于posix和unix的多用户、多任务、支持多线程和多CPU的操作系统。 Unix是20世纪70年代初出现的一个操作系统&#xff0c;除了作为网络操作系统之外&#xff0c;还可以作为单…

6路液体水位检测芯片VK36W6D SOP16 抗电源干扰及手机干扰特性好

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK36W6D 封装形式&#xff1a;SOP16/QFN16L 详细资料&#xff1a;13.5/5.474/4.703 概述 VK36W6D具有6个触摸检测通道&#xff0c;可用来检测6个点的水位。该芯片具有较高的集成度&#xff0c;仅需极少的外部组件便…

vscode GDB 调试linux内核 head.S

遇到的问题 此前参考如下文章 https://zhuanlan.zhihu.com/p/510289859 已经完成了在ubuntu 虚拟机用vscode 调试linux 内核。但是美中不足的是&#xff0c;断点最早只能加在__primary_switched() 函数。无法停在更早的断点上&#xff0c;比如ENTRY(stext) 位置。参考《奔跑吧…

C语言_初识C语言指针

文章目录 前言一、指针 ... 一个内存单元多大比较合适&#xff1f;二、地址或者编号如何产生&#xff1f;三、指针变量的大小 前言 内存是电脑上特别重要的存储器&#xff0c;计算机中程序的运行都是在内存中进行的。 所以为了有效的使用内存&#xff0c;就把内存划分成一个个…

记1次前端性能优化之CPU使用率

碰到这样的一个问题&#xff0c;用户反馈页面的图表一直加载不出来&#xff0c;页面还卡死 打开链接页面&#xff0c;打开控制台 Network 看到有个请求一直pending&#xff0c;结合用户描述&#xff0c;页面一直loading,似乎验证了我的怀疑&#xff1a;后端迟迟没有相应。 但是…

【工作笔记-0038】mongodb mongorestore 命令行导入 bson.gz数据

1. 导出的集合文件格式如下&#xff08;也就是导出的表文件&#xff09;&#xff1a; 例如&#xff1a; D:\Files\xxxx集合名称.bson.gz 怎样导出&#xff0c;这里不做介绍&#xff0c;用 mongodb compass 或者 studio 3t 都可以 2. 下载命令行导入工具&#xff1a; 官方…

webpack(一)模块化

模块化演变过程 阶段一&#xff1a;基于文件的划分模块方式 概念&#xff1a;将每个功能和相关数据状态分别放在单独的文件里 约定每一个文件就是一个单独的模块&#xff0c;使用每个模块&#xff0c;直接调用这个模块的成员 缺点&#xff1a;所有的成员都可以在模块外被访问和…

Redis发布订阅

Redis发布订阅 Redis 发布订阅(pub/sub)是一种 消息通信模式&#xff1a;发送者(pub)发送消息&#xff0c;订阅者(sub)接收消息。 Redis 客户端可以订阅任意数量的频道。 订阅/发布消息图&#xff1a; 下图展示了频道 channel1 &#xff0c; 以及订阅这个频道的三个客户端 —…