JavaSE 泛型

目录

  • 1 泛型类的定义
    • 1.1 为什么需要泛型
    • 1.2 泛型的概念
    • 1.3 泛型的分类
  • 2 泛型类
    • 2.1 泛型类的定义
    • 2.2 泛型类的例子
    • 2.3 泛型类的实例化
      • 2.3.1 实例化语法
      • 2.3.2 裸类型(Raw Type)
    • 2.4 泛型类的定义-类型边界
    • 2.5 泛型类的使用-通配符(Wildcards)
      • 2.5.1 基本概念
      • 2.5.2 通配符-上界
      • 2.5.3 通配符-下界
    • 2.6 泛型中的父子类型
  • 3 泛型方法
    • 3.1 语法格式
    • 3.2 示例
  • 4 泛型接口
  • 5 类型擦除
    • 5.1 什么是类型擦除
    • 5.2 类型擦除的规则
  • 6 泛型的优缺点

1 泛型类的定义

1.1 为什么需要泛型

假设我们自定义了一个简单的数组类,如下:

package generic2;import java.util.Stack;
/*
* Object:是所有类的父类
* */
class MyStack{public int[] elem;public int top;public MyStack(){this.elem = new int[10];}public void push(int val){this.elem[top] = val;top++;}public int getTop(){return this.elem[top-1];}
}
public class TestDemo1 {public static void main(String[] args) {// 创建一个MyStack对象,里面存储int类型的数据MyStack myStack = new MyStack();myStack.push(1);// 但是,如果创建一个MyStack对象,里面想要存储double或者String类型的数据// 遗憾的是代码不能通过编译myStack.push(1.0);myStack.push("feihan");}
}

通过上述示例发现,MyStack类中实际只能保存int类型的数据,对于其他类型的数据比如:double、String或者自定义类型的对象,根本无法存储。
想要解决上述问题,最简单的方式就是:对于不同的类型,分别实现各自MyStack类即可,但是估计你可能不愿意。
有大佬是按照如下方式改进的:将上述代码中存储数据的类型全部有int改为Object,因为在Java中Object是所有类的基类。具体代码示例如下所示:

package generic2;import java.util.Stack;
/*
* Object:是所有类的父类
* */
class MyStack{//public int[] elem;public Object[] elem;public int top;public MyStack(){//this.elem = new int[10];this.elem = new Object[10];}//public void push(int val){public void push(Object val){this.elem[top] = val;top++;}//public int getTop(){public Object getTop(){return this.elem[top-1];}
}
public class TestDemo1 {public static void main(String[] args) {MyStack myStack = new MyStack();myStack.push(1);myStack.push(1.0);myStack.push("feihan");}
}

经改过之后的 MyStack终于任意类型都可以存储了,最后:代码只需实现一份,但是任意类型都可以存储,貌似一切都比较美好。
但是大家使用之后,纷纷吐槽:因为Object是所有类的基类,那就意味着可以在一个 MyStack中存储不同种类的数据类型喽:

package generic2;import java.util.Stack;
/*
* Object:是所有类的父类
* */
class MyStack{//public int[] elem;public Object[] elem;public int top;public MyStack(){//this.elem = new int[10];this.elem = new Object[10];}//public void push(int val){public void push(Object val){this.elem[top] = val;top++;}//public int getTop(){public Object getTop(){return this.elem[top-1];}
}
public class TestDemo1 {public static void main(String[] args) {MyStack myStack = new MyStack();myStack.push(1);myStack.push(1.0);myStack.push("feihan");for(int i = 0; i < myStack.size(); ++i){String s = (String)myStack.get(i);System.out.print(s + " ");}}
}

虽然代码可以通过编译,但是如果想要遍历MyStack中的数据,怎么遍历啊?
上述代码在运行期间报错:

Exception in thread “main” java.lang.ClassCastException:java.lang.Integer cannot be cast to java.lang.String

运行时出错的原因非常简单:上述代码中,由于MyStack存储数据不都全是String类型的,那如果强转成String类型之后,肯定会发生类型转换异常。

以上就是JDK1.5之前的解决方式,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要作显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以在预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。为了解决该问题,JDK1.5中引入了泛型。

package generic2;import java.util.Stack;
/*
* Object:是所有类的父类
* */
class MyStack{//public int[] elem;public Object[] elem;public int top;public MyStack(){//this.elem = new int[10];this.elem = new Object[10];}//public void push(int val){public void push(Object val){this.elem[top] = val;top++;}//public int getTop(){public Object getTop(){return this.elem[top-1];}
}
public class TestDemo1 {public static void main(String[] args) {/*Stack<Integer> stack1 = new Stack<>();Stack<String> stack2 = new Stack<>();Stack<Double> stack3 = new Stack<>();*/MyStack myStack = new MyStack();myStack.push(1);myStack.push(1.0);myStack.push("feihan");String str = (String) myStack.getTop();System.out.println(str);}
}

1.2 泛型的概念

泛型是java1.5中增加的一个新特性,通过泛型可以写与类型无关的代码,即编写的代码可以被很多不同类型的对象所重用,经常用在一些通用的代码实现中,比如:java集合框架中的类几乎都是用泛型实现的。

泛型的本质是: 类型参数化。类似函数传参一样,传递不同的实参,函数运行完将会产生不同的结果。

1.3 泛型的分类

泛型主要包含:泛型类、泛型方法和泛型接口,后序逐一进行介绍。

2 泛型类

2.1 泛型类的定义

class 泛型类名称<类型形参列表> {// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> {// 类实现体
}

了解: 【规范】类型形参一般使用一个大写字母表示,常用的名称有:

  1. E 表示 Element
  2. K 表示 Key
  3. V 表示 Value
  4. N 表示 Number
  5. T 表示 Type
  6. S, U, V 等等 - 第二、第三、第四个类型

2.2 泛型类的例子

对上述MyStack类进行改造,将其写成泛型类。
注意:以下实现中,没有考虑过多的细节问题,比如插入元素时空间不够如何处理,此处主要演示泛型类的语法规则。
具体代码示例如下所示:

package generic2;import java.util.Stack;
// 在实现MyStack泛型类时,T具体代表什么类型实现者不关心
// 当对泛型类进行实例化时,编译器才知道T具体代表什么类型
//class MyStack{
class MyStack<T>{//public int[] elem;//public Object[] elem;public T[] elem;public int top;public MyStack(){//this.elem = new int[10];//this.elem = new Object[10];//this.elem = new T[10];// 此处为什么new Object[],为什么需要强转后文中会解释this.elem = (T[])new Object[10];}//public void push(int val){//public void push(Object val){public void push(T val){this.elem[top] = val;top++;}//public int getTop(){//public Object getTop(){public T getTop(){return this.elem[top-1];}
}

2.3 泛型类的实例化

2.3.1 实例化语法

泛型类<类型实参> 变量名; 定义一个泛型类引用。
new 泛型类<类型实参>(构造方法实参); 实例化一个泛型类对象。

package generic2;
import java.util.Stack;
/*
* Object:是所有类的父类
*
* 泛型:
* 1.class MyStack<T>  此时的<T>:代表占位符,表示当前这个类是一个泛型类
* 2.this.elem = new T[10]; 此时不能实例化泛型类型的数组对象
* 3.MyStack<Integer> myStack = new MyStack<>();
*   MyStack<Integer> 这里指定当前类可以存放的数据类型
*   new MyStack<>(); 也可以写成new MyStack<Integer>(); 这里的这个Integer写不写都可以
* 4.泛型的意义:
*     a:可以自动进行类型的检查
*     b:可以自动进行类型的转换
* 5.MyStack<int> myStack = new MyStack<>();
*   简单类型不能做泛型类型的参数  包装类型也是引用类型的一种
* 6.泛型到底是怎么编译的? 擦除机制
*   擦除为Object的意义就是:可以放任意类型的数据
*   运行java程序的时候 是没有泛型的概念的
* 7.MyStack<Integer> myStack 泛型类型的参数 不参与类型的组成
* */// 在实现MyStack泛型类时,T具体代表什么类型实现者不关心
// 当对泛型类进行实例化时,编译器才知道T具体代表什么类型
//class MyStack{
class MyStack<T>{//public int[] elem;//public Object[] elem;public T[] elem;public int top;public MyStack(){//this.elem = new int[10];//this.elem = new Object[10];//this.elem = new T[10];// 此处为什么new Object[],为什么需要强转后文中会解释this.elem = (T[])new Object[10];}//public void push(int val){//public void push(Object val){public void push(T val){this.elem[top] = val;top++;}//public int getTop(){//public Object getTop(){public T getTop(){return this.elem[top-1];}
}
public class TestDemo1 {public static void main(String[] args) {/*Stack<Integer> stack1 = new Stack<>();Stack<String> stack2 = new Stack<>();Stack<Double> stack3 = new Stack<>();*///MyStack myStack = new MyStack();// 将泛型类使用Integer类型来实例化,表明myStack中只能存放Integer类型的对象MyStack<Integer> myStack = new MyStack<>();myStack.push(1);myStack.push(11);myStack.push(111);//myStack.push(1.0);//myStack.push("feihan");//String str = (String) myStack.getTop();//System.out.println(str);// 此处从myStack中获取到的成员,再不需要进行强制类型转换了int a = myStack.getTop();System.out.println(a);MyStack<String> myStack2 = new MyStack<>();myStack2.push("feihan");//假设不指定泛型的类型参数/** 强制压制警告* @SuppressWarnings("unchecked")* MyStack<String> myStack3 = new MyStack();* */MyStack myStack3 = new MyStack();myStack3.push(1);myStack3.push("feihan");myStack3.push(1.0);//这里为啥三种类型都可以,因为我们发现假设不指定泛型的类型参数,它默认为Object类}
}

注意:

  1. 右侧<>中的类型可以省略
MyStack<Integer> myStack = new MyStack<>();

在new MyStack<>()对象时,<>中未明确指明类型,编译器会根据=左侧<>中的类型来推演。

  1. 左侧<>中的类型不能省略
MyStack<> myStack = new MyStack<Integer>();// 省略之后,编译失败

编译器在推演时,是根据左侧类型来推演右侧的。

  1. 虽然右侧<>可以不用写类型,但是<>不能省略
MyStack<String> myStack3 = new MyStack();// 自己永远不要这么用

上述代码,会产生编译警告:

Note: Example.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

可以使用 @SuppressWarnings 注解进行警告压制:

@SuppressWarnings("unchecked")

2.3.2 裸类型(Raw Type)

裸类型是一个泛型类但没有带着类型实参,例如MyStack就是一个裸类型

MyStack myStack3 = new MyStack();

注意: 我们不要自己去使用裸类型,裸类型是为了兼容老版本的 API 保留的机制。
通过上面代码中的最后myStack3这一部分可以看到:如果类型裸类型时,泛型类中的T会被默认当成Object来处理,那就回到了JDK1.5之前的情况。下面的类型擦除部分,我们也会讲到编译器是如何使用裸类型的。

2.4 泛型类的定义-类型边界

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。

class 泛型类名称<E extends U> {
...
}

在实例化时,E只能是U的子类,否则编译会报错。
具体示例代码1:

package generic2;
import java.util.Stack;
/*
* 写一个泛型类算法,找到list当中的最大值
* *///将来对Algorithm进行实例化时,实例化的类型必须要是Comparable<T>的子类才可以
//class Algorithm<T>{
class Algorithm<T extends  Comparable<T> >{public T findMaxVal(T[] array){T max = array[0];for (int i = 1; i < array.length ; i++) {//if(array[i] >= max){   这里为啥会报错?---->因为T类型是一个引用类型,引用类型只能用compareTo来比较大小,用equals来比较相等//if(array[i].compareTo(max) >= 0){  T类型引用的擦除机制擦除为Object类型,但Object中没有compareTo这个接口,所以这里会报错//修改方法为: class Algorithm<T extends  Comparable<T> >if (array[i].compareTo(max) >= 0)max = array[i];}return max;}
}
/*
* 泛型方法
* */
class Algorithm2{public static<T extends  Comparable<T>> T findMaxVal(T[] array){T max = array[0];for (int i = 1; i < array.length ; i++) {//if(array[i] >= max){   这里为啥会报错?---->因为T类型是一个引用类型,引用类型只能用compareTo来比较大小,用equals来比较相等//if(array[i].compareTo(max) >= 0){  T类型引用的擦除机制擦除为Object类型,但Object中没有compareTo这个接口,所以这里会报错//修改方法为: class Algorithm<T extends  Comparable<T> >if (array[i].compareTo(max) >= 0)max = array[i];}return max;}
}
class Person{}
public class TestDemo1 {public static void main(String[] args) {Integer[] array = {1,2,3,4,5,6,7};System.out.println(Algorithm2.findMaxVal(array));System.out.println(Algorithm2.<Integer>findMaxVal(array));}public static void main3(String[] args) {Algorithm<Integer> algorithm = new Algorithm<>();Integer[] array = {1,2,3,4,5,6,7};System.out.println(algorithm.findMaxVal(array));//Algorithm<Person> algorithm1 = new Algorithm<>();}}

具体示例代码2:

// 将来对MyArray进行实例化时,实例化的类型必须要是Animal的子类才可以
public class MyArray<E extends Animal> {private E[] array = null;private int size;private int capacity;public MyArray(int capacity){array = (E[])new Object[capacity];size = 0;this.capacity = capacity;}// ...public static void main(String[] args) {// 编译成功,因为Dog是Animal的子类MyArray<Dog> m1 = new MyArray<>(10);m1.add(new Dog("旺财"));m1.add(new Dog("二哈"));// 编译成功,因为Cat是Animal的子类MyArray<Cat> m2 = new MyArray<>(10);m2.add(new Cat("肥波"));m2.add(new Cat("加菲"));// 编译失败,因为String不是Animal的子类MyArray<String> m3 = new MyArray<>(10);
}
}

注意: 没有指定类型边界 E,可以视为 E extends Object。

2.5 泛型类的使用-通配符(Wildcards)

2.5.1 基本概念

? 用于在泛型的使用,即为通配符。
具体示例代码1:

package generic2;import java.util.ArrayList;
import java.util.Stack;
/*
* Object:是所有类的父类
*
* 泛型:
* 1.class MyStack<T>  此时的<T>:代表占位符,表示当前这个类是一个泛型类
* 2.this.elem = new T[10]; 此时不能实例化泛型类型的数组对象
* 3.MyStack<Integer> myStack = new MyStack<>();
*   MyStack<Integer> 这里指定当前类可以存放的数据类型
*   new MyStack<>(); 也可以写成new MyStack<Integer>(); 这里的这个Integer写不写都可以
* 4.泛型的意义:
*     a:可以自动进行类型的检查
*     b:可以自动进行类型的转换
* 5.MyStack<int> myStack = new MyStack<>();
*   简单类型不能做泛型类型的参数  包装类型也是引用类型的一种
* 6.泛型到底是怎么编译的? 擦除机制
*   擦除为Object的意义就是:可以放任意类型的数据
*   运行java程序的时候 是没有泛型的概念的
* 7.MyStack<Integer> myStack 泛型类型的参数 不参与类型的组成
* 8.泛型的上界:
*   class Algorithm<T extends  Comparable<T> >{}
*   T:T类型 一定要实现Comparable接口
*
*   class Algorithm<T extends  Animal >{}
*   E:可以是Animal的子类 或者是 Animal自己类本身
* 9.泛型没有下界
* 10.泛型方法(一定是静态的):
*   public static<T> T findMaxVal(T[] array){
*   public static<T extends  Comparable<T>> T findMaxVal(T[] array){
* 11.通配符:通配符实际上也是一种泛型。一般用在源码当中居多一点。
*    泛型一般用于读取和写入
*    通配符一般用于读取
*
*    上界:<? extends E>表示传入的参数? 是上界E的子类或者E自己本身
*    下界:<? super E> 表示传入的参数? 是下界E的父类或者E自己本身
* 12.ArrayList<Integer> list1 和ArrayList<Number> list2 他们直接是否构成父子类关系?
*    不是这样子的:之前说过了<>里面的内容会被擦除
* *//*
* 写一个泛型方法 打印一个list当中的所有的数据
* 通配符:通配符实际上也是一种泛型。一般用在源码当中居多一点。
* 泛型一般用于读取和写入
* 通配符一般用于读取
*
* 上界:<? extends E>表示传入的参数? 是上界E的子类或者E自己本身
* 下界:<? super E> 表示传入的参数? 是下界E的父类或者E自己本身
* */
class Test{/* public static<T> void print(ArrayList<T> list){for (T x:list) {System.out.println(x);}}*/public static void print(ArrayList<?> list){for (Object x:list) {System.out.println(x);}}
}
public class TestDemo1 {public static void main(String[] args) {//Integer extends NumberArrayList<Integer> list1 = new ArrayList<>();ArrayList<Number> list2 = new ArrayList<>();list2.addAll(list1);}public static void main5(String[] args) {ArrayList<Integer> list1 = new ArrayList<>();list1.add(1);list1.add(2);list1.add(3);Test.print(list1);ArrayList<Double> list2 = new ArrayList<>();list2.add(1.0);list2.add(2.0);list2.add(3.0);Test.print(list2);}}

具体示例代码2:

public class MyArray<E> {...}// 可以传入任意类型的 MyArray
public static void printAll(MyArray<?> m) {
...
}
// 以下调用都是正确的
printAll(new MyArray<String>());
printAll(new MyArray<Integer>());
printAll(new MyArray<Double>());
printAll(new MyArray<Number>());
printAll(new MyArray<Object>());

2.5.2 通配符-上界

语法:

<? extends 上界>

具体示例代码1:

// 传入类型实参是 Animal 子类的任意类型的 MyArray
public static void printAll(MyArray<? extends Animal> m) {
...
}
// 以下调用都是正确的
printAll(new MyArray<Cat>());
printAll(new MyArray<Dog>());
// 以下调用是编译错误的
printAll(new MyArray<String>());
printAll(new MyArray<Object>());

注意: 需要区分 泛型使用中的通配符上界 和 泛型定义中的类型上界。

2.5.3 通配符-下界

语法:

<? super 下界>

具体示例代码1:

// 可以传入类型实参是 Cat 父类的任意类型的 MyArray
public static void printAll(MyArray<? super Cat> list) {
...
}
// 以下调用都是正确的
printAll(new MyArrayList<Cat>());
printAll(new MyArrayList<Animal>());
printAll(new MyArrayList<Object>());
// 以下调用是编译错误的
printAll(new MyArrayList<String>());
printAll(new MyArrayList<Dog>());

2.6 泛型中的父子类型

具体示例代码1:

public class MyArray<E> { ... }
// MyArray<Object> 不是 MyArray<Animal> 的父类型
// MyArray<Animal> 也不是 MyArray<Cat> 的父类型
// 需要使用通配符来确定父子类型
// MyArray<?> 是 MyArray<? extends Animal> 的父类型
// MyArray<? extends Animal> 是 MyArrayList<Dog> 的父类型

3 泛型方法

3.1 语法格式

方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { … }

3.2 示例

具体示例代码1:

public class Util {public static <E> void swap(E[] array, int i, int j) {E t = array[i];array[i] = array[j];array[j] = t;}
}// 没有显式指定类型,编译期间需要进行类型推到
Integer[] a = { ... };
swap(a, 0, 9);
String[] b = { ... };
swap(b, 0, 9);
// 显式指定类型,编译期间,不用进行类型推导
Integer[] a = { ... };
Util.<Integer>swap(a, 0, 9);
String[] b = { ... };
Util.<String>swap(b, 0, 9);

4 泛型接口

// 与定义泛型类非常相似---该接口主要是用来对对象进行比较的
// 比如sort方法,可以排任意类型的数据,可以排升序也可以排降序
// sort在排序过程中,元素的比较规则就可以通过来实现该 泛型接口 来处理
public interface Comparator<T> {int compare(T o1, T o2);
}

5 类型擦除

5.1 什么是类型擦除

Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(Type Erasure),将所有的泛型表示(尖括号中的内容)都“替换”为具体的类型(其对应的原生态类型),就像完全没有泛型一样。 即泛型类和普通类在 java 虚拟机内是没有什么特别的地方。
注意:

  1. 泛型:只存在于编译时期 只是编译时期
  2. 泛型的意义:
    a:自动进行类型的检查
    b:自动进行类型转换
  3. 泛型在编译的时候,并不会进行指定类型的替换,而是拿着指定的类型进行检查,也就是说在编译的时候,拿着你指定的类型进行检查,记住并没有说是替换。
  4. 编译的时候会进行类型擦除,编译的时候 编译都会把泛型擦除为Object,不是替换为Object。

在这里插入图片描述

5.2 类型擦除的规则

泛型的类型擦除原则是:

  1. 消除类型参数声明,即删除<>及其包围的部分。
  2. 根据类型参数的上下界推断并替换所有的类型参数为原生态类型:如果类型参数是无限制通配符或没有上下界限定则替换为Object,如果存在上下界限定则根据子类替换原则取类型参数的最左边限定类型(即父类)。
  3. 为了保证类型安全,必要时插入强制类型转换代码。
  4. 自动产生“桥接方法”以保证擦除类型后的代码仍然具有泛型的“多态性”。
// 1. 无限制类型擦除---<E>和<?>类型参数都被替换为Object
class MyArray<E> {// E 会被擦除为 Object
}// 2. 有限制类型擦除---<T extends Animal>和<? extends Animal>的类型参数被替换为Animal
// <? super Animal>被替换为Object
class MyArray<E extends Animal> {// E 被擦除为 Animal
}// 3. 擦除方法中的类型参数
public class Util {public static <E> void swap(E[] array, int i, int j) {// ...// <E>删除掉 E被擦除为Object
}
}

总结: 即类型擦除主要看其类型边界而定。
注意: 编译器在类型擦除阶段在做什么?

  1. 将类型变量用擦除后的类型替换,即 Object 或者 Comparable;
  2. 加入必要的类型转换语句;
  3. 加入必要的 bridge method 保证多态的正确性。

6 泛型的优缺点

泛型的优点:

  1. 提高代码的复用性;
  2. 提高开发效率;
  3. 可以实现一些通用类型的容器或算法。

泛型的缺点:

  1. 泛型类型参数不支持基本数据类型;
  2. 无法实例化泛型类型的对象;
  3. 无法使用泛型类型声明静态的属性;
  4. 无法使用 instanceof 判断带类型参数的泛型类型;
  5. 无法创建泛型类数组;
  6. 无法 create、catch、throw 一个泛型类异常(异常不支持泛型);
  7. 泛型类型不是形参一部分,无法重载。

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

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

相关文章

HTML_有哪些字体样式及使用

文章目录 &#x1f431;‍&#x1f409;一、字体样式的基本概念&#xff1a;&#x1f431;‍&#x1f409;二、css字体样式属性有&#xff1a;&#x1f923;1、设置字体类型&#xff08;font-family&#xff09;&#x1f923;2、设置字体大小&#xff08;font-size&#xff09;…

【lesson19】MySQL内置函数(2)数学函数和其它函数

文章目录 数学函数函数使用 其它函数函数使用 数学函数 函数使用 其它函数 函数使用 user() 查询当前用户 database()显示当前正在使用的数据库 password()函数&#xff0c;MySQL数据库使用该函数对用户加密 md5(str)对一个字符串进行md5摘要&#xff0c;摘要后得到一个32…

VueStu02-创建一个Vue实例

一、核心步骤 1.准备容器 准备一个盒子div。 2.引包 从官网引包&#xff0c;有开发版本和生产版本之分。 3.创建Vue实例 创建一个Vue实例&#xff0c;new Vue()。 4.指定配置项 指定配置项&#xff0c;用于渲染数据 。 el&#xff1a;指定挂载点。知道自己将来要管理的是…

Axure的交互以及情形的介绍

一. 交互 1.1 交互概述 通俗来讲就是&#xff0c;谁用了什么方法做了什么事情&#xff0c;主体"谁"对应的就是axure中的元件&#xff0c;"什么方法"对应的就是交互事件&#xff0c;比如单击事件、双击事件&#xff0c;"什么事情"对应的就是交互…

Temu、Shein、OZON测评自养号,IP和指纹浏览器的优缺点分析

随着全球电子商务的飞速发展&#xff0c;跨境电商环境展现出巨大的潜力和机遇。然而&#xff0c;跨境卖家们也面临着更激烈的竞争、更严格的规定和更高的运营成本等挑战。为了在这个环境中脱颖而出&#xff0c;一些卖家尝试使用自动脚本程序进行浏览和下单。然而&#xff0c;这…

JAVA分库分表

1.1为什么需要分库分表 随着平台的发展&#xff0c;平台的数据会越来越多。当表中的数据量过多时&#xff0c;数据库的性能会下降严重&#xff0c;很有可能会把系统给拖垮。类似于分而治之的思想&#xff0c;将大的问题拆分成小的问题&#xff0c;从而提高效率。通过将数据分散…

3分钟让你学会axios在vue项目中的基本用法(建议收藏)

目录 Axios Axios简介 一、axios是干啥的 二、安装使用 三、Axios请求方式 1、axios可以请求的方法&#xff1a; 2、get请求 3、post请求 4、put和patch请求 5、delete请求 6、并发请求 四、Axios实例 1、创建axios实例 2、axios全局配置 3、axios实例配置 4、…

CTF命令执行部分总结

&#x1f60b;大家好&#xff0c;我是YAy_17&#xff0c;是一枚爱好网安的小白&#xff0c;正在自学ing。 本人水平有限&#xff0c;欢迎各位大佬指点&#xff0c;一起学习&#x1f497;&#xff0c;一起进步⭐️。 ⭐️此后如竟没有炬火&#xff0c;我便是唯一的光。⭐️ 关于…

矩阵式键盘实现的电子密码锁

#include<reg51.h> //包含51单片机寄存器定义的头文件 sbit P14P1^4; //将P14位定义为P1.4引脚 sbit P15P1^5; //将P15位定义为P1.5引脚 sbit P16P1^6; //将P16位定义为P1.6引脚 sbit P17P1^7; //将P17位定义为P1.7引脚 sbit soundP3^7; //将so…

[AutoSar]基础部分 RTE 01 介绍

目录 关键词平台说明一、什么是RTE二、RTE的主要功能 关键词 嵌入式、C语言、autosar、EcuM、wakeup、flex 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、什么是RTE RTE&#xff08;Run-Time Environment&…

【python】进阶--->并发编程之线程(二)

一、线程的生命周期 新建 : 创建线程经过初始化,进入就绪状态 就绪 : 等待操作系统调度,调度后进入运行状态运行 阻塞 : 暂停运行,解除阻塞后进入就绪等待重新调度 消亡 : 线程执行完毕或者异常终止 可能有3种情况从运行到阻塞 : 同步 : 线程中获取同步锁,但是资源已经被其他…

车辆跟踪及测距

车辆跟踪及测距是一种现代化的技术手段&#xff0c;通过使用各种传感器和技术设备&#xff0c;能够实现车辆的实时监控和测距。这些技术手段包括GPS全球定位系统、雷达、激光等&#xff0c;它们可以帮助我们更好地了解车辆的位置和行驶情况。在本文中&#xff0c;我们将从以下几…

LeetCode - 460 LFU缓存(Java JS Python)

题目来源 460. LFU 缓存 - 力扣&#xff08;LeetCode&#xff09; 题目描述 请你为 最不经常使用&#xff08;LFU&#xff09;缓存算法设计并实现数据结构。 实现 LFUCache 类&#xff1a; LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象int get(int key)…

【迁移学习论文四】Multi-Adversarial Domain Adaptation论文原理及复现工作

Multi-Adversarial Domain Adaptation 多对抗域适应 前言 好久没有更新了&#xff0c;所以这周开始记录下来&#xff0c;也好督促自己。记录本人预备研究生阶段相关迁移学习论文的原理阐述以及复现工作。 问题 跨域混淆或错误对齐 文章介绍 这篇文章于2018年发表在AAAI&…

手把手教你使用Cypress进行端到端测试

一、引言 Cypress是一个流行的端到端测试框架&#xff0c;它提供了一个全面的解决方案&#xff0c;可以测试任何在浏览器中运行的内容。不论你是想为一个小型项目添加测试&#xff0c;还是在大型企业级应用中进行端到端测试&#xff0c;Cypress都是一个不错的选择。本文将会手…

智能优化算法应用:基于阿基米德优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于阿基米德优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于阿基米德优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.阿基米德优化算法4.实验参数设定…

国家开放大学 河南开放大学形成性考核 平时作业 统一参考资料

试卷代号&#xff1a;1258 房屋建筑混凝土结构设计 参考试题 一、单项选择题&#xff08;每小题2分&#xff0c;共计40分&#xff09; 1.( )是将框架结构中的部分跨间布置剪力墙或把剪力墙结构的部分剪力墙抽掉改为框架承重。 A.梁板结构体系 B.框…

评价机器学习模型的指标

为了衡量一个机器学习模型的好坏&#xff0c;需要给定一个测试集&#xff0c;用模型对测试集中的每一个样本进行预测&#xff0c;并根据预测结果计算评价分数。 对于分类问题&#xff0c;常见的评价标准有准确率、精确率、召回率和F值等。给定测试集 &#x1d4af; {(&#x1…

一款电压检测LVD

一、基本概述 The TX61C series devices are a set of three terminal low power voltage detectors implemented in CMOS technology. Each voltage detector in the series detects a particular fixed voltage ranging from 0.9V to 5.0V. The voltage detectors consist…

git缓存区、本地仓库、远程仓库的同步问题(初始化库无法pull和push)

git新建库与本地库同步 gitee使用教程&#xff0c;git的下载与安装接不在叙述了。 新建远程仓库 新建远程仓库必须要使用仓库提供的api&#xff0c;也就是仓库门户网站&#xff0c;例如gitee&#xff0c;github&#xff0c;gitlab等。在上图中使用gitee网址中新建了一个test仓…