当前位置: 首页 > news >正文

十二、集合(2)

本章概要

  • 添加元素组
  • 集合的打印
  • 列表 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()); // ExceptionList<Snow> snow2 = Arrays.asList(new Light(), new Heavy());//- snow2.add(new Slush()); // ExceptionList<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 resizesSystem.out.println("2: " + pets);System.out.println("3: " + pets.contains(h));pets.remove(h); // Remove by objectPet 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 indexSystem.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 sortSystem.out.println("sorted subList: " + sub);// Order is not important in containsAll():System.out.println("11: " + pets.containsAll(sub));Collections.shuffle(sub, rand); // Mix it upSystem.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 copycopy.remove(2); // Remove by indexSystem.out.println("14: " + copy);copy.removeAll(sub); // Only removes exact objectsSystem.out.println("15: " + copy);copy.set(1, new Mouse()); // Replace an elementSystem.out.println("16: " + copy);copy.addAll(2, sub); // Insert a list in the middleSystem.out.println("17: " + copy);System.out.println("18: " + pets.isEmpty());pets.clear(); // Remove all elementsSystem.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();@Overridepublic Pet get() { // Create one random Petint 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() {}@Overridepublic String toString() {return getClass().getSimpleName() +(name == null ? "" : " " + name);}public long id() {return id;}@Overridepublic boolean equals(Object o) {return o instanceof Individual &&Objects.equals(id, ((Individual) o).id);}@Overridepublic int hashCode() {return Objects.hash(name, id);}@Overridepublic 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 finalList<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 finalList<Class<? extends Pet>> TYPES =ALL_TYPES.subList(ALL_TYPES.indexOf(Mutt.class),ALL_TYPES.size());@Overridepublic 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() 方法,可以在所产生的数组中的对象上调用这个方法。

相关文章:

十二、集合(2)

本章概要 添加元素组集合的打印列表 List 添加元素组 在 java.util 包中的 Arrays 和 Collections 类中都有很多实用的方法&#xff0c;可以在一个 Collection 中添加一组元素。 Arrays.asList() 方法接受一个数组或是逗号分隔的元素列表&#xff08;使用可变参数&#xff…...

【网络设备】交换机的概念、工作原理、功能以及以太网帧格式

个人主页&#xff1a;insist--个人主页​​​​​​ 本文专栏&#xff1a;网络基础——带你走进网络世界 本专栏会持续更新网络基础知识&#xff0c;希望大家多多支持&#xff0c;让我们一起探索这个神奇而广阔的网络世界。 目录 一、认识交换机 二、交换机的主要功能 1、数…...

研磨设计模式day11观察者模式

目录 场景 代码示例 定义 观察者模式的优缺点 本质 何时选用 简单变型-区别对待观察者 场景 我是一家报社&#xff0c;每当我发布一个新的报纸时&#xff0c;所有订阅我家报社的读者都可以接收到 代码示例 报纸对象 package day11观察者模式;import java.util.Observ…...

第八周第二天学习总结 | MySQL入门及练习学习第四天

实操练习&#xff1a; 1.建立一个员工表和与之对应的部门表 2.建立外键约束 3.使用多表查询&#xff0c;直接查询部门表和员工表 发现&#xff1a;有很多多余的因笛卡尔乘积而带来的多余输出内容 我想要的到简单明了的数据结果&#xff0c;要消除多于因笛卡尔乘积带来的输出…...

WPF数据转换

在基本绑定中&#xff0c;信息从源到目标的传递过程中没有任何变化。这看起来是符合逻辑的&#xff0c;但我们并不总是希望出现这种行为。通常&#xff0c;数据源使用的是低级表达方式&#xff0c;我们可能不希望直接在用户界面使用这种低级表达方式。WPF提供了两个工具&#x…...

《Go 语言第一课》课程学习笔记(十三)

方法 认识 Go 方法 Go 语言从设计伊始&#xff0c;就不支持经典的面向对象语法元素&#xff0c;比如类、对象、继承&#xff0c;等等&#xff0c;但 Go 语言仍保留了名为“方法&#xff08;method&#xff09;”的语法元素。当然&#xff0c;Go 语言中的方法和面向对象中的方…...

基于RUM高效治理网站用户体验入门-价值篇

用户体验 用户体验基本包含访问网站的性能、可用性和正确性。通俗的讲&#xff0c;就是一把通过用户访问测量【设计者】意图的尺子。 本文目的 网站如何传递出设计者的意图&#xff0c;可能页面加载时间太长、或者页面在用户的浏览器中渲染时间太慢&#xff0c;或者第三方设备…...

Unity之Photon PUN2开发多人游戏如何实现组队功能

前言 Photon Unity Networking 2 (PUN2) 是一款基于Photon Cloud的Unity多人游戏开发框架。它提供了一系列易于使用的API和工具,使开发者可以快速构建多人戏,并轻松处理多人游戏中的网络同步、房间管理、玩家匹配等问题。 我们在查看Pun2的Demo时,会发现Demo中自带了一个简…...

大数据Flink简介与架构剖析并搭建基础运行环境

文章目录 前言Flink 简介Flink 集群剖析Flink应用场景Flink基础运行环境搭建Docker安装docker-compose文件编写创建并运行容器访问Flink web界面 前言 前面我们分别介绍了大数据计算框架Hadoop与Spark,虽然他们有的有着良好的分布式文件系统和分布式计算引擎&#xff0c;有的有…...

RISC-V IOPMP实际用例-Rapid-k模型在NVIDIA上的应用

安全之安全(security)博客目录导读 2023 RISC-V中国峰会 安全相关议题汇总 说明&#xff1a;本文参考RISC-V 2023中国峰会如下议题&#xff0c;版权归原作者所有。...

【UE5】给模型指定面添加自定义材质

实现步骤 1. 首先我们向UE中导入一个简单的模型&#xff0c;可以看到目前该模型的材质插槽只有一个&#xff0c;当我们修改材质时会使得模型整体的材质全部改变&#xff0c;如果我们只想改变模型的某些面的材质就需要继续做后续操作。 2. 选择建模模式 3. 在模式工具栏中点击…...

mall:redis项目源码解析

文章目录 一、mall开源项目1.1 来源1.2 项目转移1.3 项目克隆 二、Redis 非关系型数据库2.1 Redis简介2.2 分布式后端项目的使用流程2.3 分布式后端项目的使用场景2.4 常见的缓存问题 三、源码解析3.1 集成与配置3.1.1 导入依赖3.1.2 添加配置3.1.3 全局跨域配置 3.2 Redis测试…...

RISC-V Linux系统kernel制作

文章目录 1、下载2、编译 1、下载 Linux 官网地址:https://www.kernel.org $ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.181.tar.xz $ tar xvf linux-5.10.181.tar.xz $ cd linux-5.10.1812、编译 安装依赖 $ sudo apt-get install -y flex bison bui…...

5G NR:PRACH时域资源

PRACH occasion时域位置由高层参数RACH-ConfigGeneric->prach-ConfigurationIndex指示&#xff0c;根据小区不同的频域和模式&#xff0c;38.211的第6.3.3节中给出了prach-ConfigurationIndex所对应的表格。 小区频段为FR1&#xff0c;FDD模式(paired频谱)/SUL&#xff0c;…...

LLaMA-2的模型架构

输入token&#xff1b;[B, L] 输出probs:[B, L, vab_size]...

掌握Java框架之Struts,开启高效开发之旅!

当今的软件开发世界&#xff0c;Java框架如Struts已经成为构建企业级应用的重要工具。Struts作为一个流行的MVC框架&#xff0c;不仅简化了Java Web开发&#xff0c;还提高了软件的可维护性和可扩展性。本文将带你走进Struts的世界&#xff0c;探索其魅力所在&#xff0c;让你领…...

关于Vue.set()

简介 Vue.set() 是 Vue 中的一个全局方法&#xff0c;其主要作用是向响应式对象添加新的属性&#xff0c;并确保新属性同样具有响应式。在 Vue.js 中&#xff0c;当数据对象的属性被直接修改时&#xff0c;Vue 可以监测到数据变化并响应变化。但若添加新的响应式对象属性时&am…...

Selenium 遇见伪元素该如何处理?

问题发生 在很多前端页面中&#xff0c;大家会见到很多&#xff1a;:before、::after 元素&#xff0c;比如【百度流量研究院】&#xff1a; 比如【百度疫情大数据平台】&#xff1a; 以【百度疫情大数据平台】为例&#xff0c;“累计确诊”文本并没有显示在 HTML 源代码中&am…...

RPA技术介绍与应用价值

一、什么是RPA技术? RPA(Robotic Process Automation)机器人流程自动化,是一种能够模拟人类来执行重复性任务的新型技术。RPA可实现统筹安排、自动化业务处理,并提升业务工作流处理效率。用户只需通过图形方式显示的计算机操作界面对RPA软件进行动态设定即可。借助RPA (R…...

产品经理,需要具备哪些能力和知识

作为产品经理&#xff0c;需要具备以下能力和知识&#xff1a; 产品管理能力&#xff1a;具备全面的产品管理能力&#xff0c;包括产品策划、需求分析、产品规划、产品设计、项目管理、市场调研和竞争分析等。 用户导向思维&#xff1a;能够理解用户需求和期望&#xff0c;以…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式 文章目录 设计模式一、socket.h 接口&#xff08;interface&#xff09;二、socket.cpp 实现&#xff08;implementation&#xff09;三、server.cpp 使用封装&#xff08;main 函数&#xff09;四、client.cpp 使用封装&#xff08;main 函数&#xff09;五、退出方法…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...

Qwen系列之Qwen3解读:最强开源模型的细节拆解

文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...