Java泛型
文章目录
- 一、泛型介绍
- 1. 背景
- 2. 概念
- 3. 好处
- 二、泛型声明
- 泛型类型符号
- 泛型声明方式
- 三、类型擦除
- 1. 什么是类型擦除
- 桥接方法
- 2. 为何需要类型擦除
- 3. 类型信息并未完全擦除
- 四、泛型使用
- 1. 泛型类
- 2. 泛型接口
- 3. 泛型方法
- 五、泛型扩展
- 1. 泛型的上下边界
- 泛型的上边界
- 泛型的下边界
- 2. 泛型中使用&(并且)操作符
一、泛型介绍
1. 背景
在JDK5之前,还没有泛型。在使用集合时,需要构建一个元素类型为Object的集合,集合能够存储任意的数据类型对象,在使用该集合的过程中,需要明确知道存储每个元素的数据类型,否则很容易引发ClassCastException异常。
2. 概念
JDK5中引入Java泛型这个新特性,泛型提供了编译时类型安全监测机制,该机制允许我们在编译时检测到非法的类型数据结构。
- 泛型主要是方便了程序员的代码编写,以及更好的安全性检测。
- 泛型是一种运用于编译时期的技术,泛型的出现,实现了把运行阶段的错误提前暴露到了编译阶段。
在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
参数化类型
泛型的本质就是参数化类型。在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型。
参数化类型,顾名思义就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
简单理解:泛型就是把类型当作是参数一样进行传递,数据类型只能是引用类型。
3. 好处
- 编译时类型安全监测
- 消除强制类型转换
二、泛型声明
泛型的使用需要先声明,声明通过<符号>的方式,符号可以任意,编译器通过识别尖括号和尖括号内的字母来解析泛型。
- 泛型的类型只能为引用类型,不能为基本类型
- 尖括号的位置也是固定的,只能在类名之后或方法返回值之前
泛型类型符号
一般约定的类型符号:
- E:Element (表示集合元素,在集合中使用)
- T:Type(表示Java类)
- K:Key(表示键,比如Map中的key)
- V:Value(表示值,比如Map中的key)
- N:Number(表示数值类型)
- ?:泛型通配符(表示不确定的Java类型)
泛型声明方式
常见声明方式:
- <T>:普通声明
- <?>:无边界声明
- <? extends 类>:上边界声明
- <? super 类>:下边界声明
需要注意:通配符?不能在泛型类(接口)的声明上使用。
三、类型擦除
1. 什么是类型擦除
Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。
官方描述:
泛型被引入Java语言,以在编译时提供更严格的类型检查,并支持泛型编程。
为了实现泛型,Java编译器将类型擦除应用于:
- 如果类型参数是无界的,则将泛型类型中的所有类型参数替换为其边界或Object。因此,生成的字节码只包含普通类、接口和方法。
- 如果需要,请插入类型强制转换以保持类型安全。
- 生成桥接方法以保留扩展泛型类型中的多态性。
类型擦除确保了不会为参数化类型创建新类;所以泛型是没有运行时开销的。
对官方描述的理解:
- 泛型的使用,使得编译器在编译时进行了更严格类型检查,避免运行时引发ClassCastException异常
- 泛型应用于编译阶段,用泛型定义的类型参数,会在编译时会去掉,这称之为“类型擦除”。编译后生成的字节码class文件不包含泛型类型信息,运行时虚拟机并不知道泛型。
- 编译时,泛型的类型参数会被替换为其边界或Object
- 编译时,使用泛型的地方会插入强制类型转换
- 在泛型父类、泛型接口的场景中,会生成桥接方法以保留泛型类型中的多态性。
- 编译时,如果子类复写的父类中的方法使用了泛型类型,子类会自动生成一个该方法的桥接方法
- 编译时,如果实现类实现接的接口方法使用了泛型类型,实现类会自动生成一个该方法的桥接方法
public class Test {public static void main(String[] args) {ArrayList<Integer> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();System.out.println(list1.getClass() == list2.getClass());}
}
打印结果为true,因为list1和list2的Class对象是同一个Class。
特别注意:对于编译后生成的字节码class文件不包含泛型类型信息这句话,网上普遍都说这个说法,但都没去仔细解释,理解的时候可能会有不解,因为你发现现实中的class文件中时是包含了泛型类型信息的。下文会解释这个问题。
桥接方法
桥接方法是JDK1.5引入泛型后,为使java泛型方法生成的字节码与JDK1.5版本之前的字节码兼容由编译器自动生成的。
子类继承父类(实现接口)实现泛型方法的情况,父类经过编译后方法的泛型类型入参和返回值类型都为Object(或上边界类型),而子类的实现方法的入参和返回值类型为具体的泛型类型(如String),此时子类并没有重写父类的方法了(返回值和形参与父类完全相同才是重写方法),所以需要编译器生成一个桥接方法达到重写父类方法的目的。
因此当子类继承父类(实现接口)实现泛型方法的时候,编译器会为子类自动生成桥接方法。
举例说明:
public interface TestInterface<T> {T get();void set(T t);
}class Test3 implements TestInterface<Integer> {@Overridepublic Integer get() {return null;}@Overridepublic void set(Integer s) {}
}
class MainClass {public static void main(String[] args) {Method[] methods = Test3.class.getDeclaredMethods();for (Method method : methods) {System.out.println((method.isBridge() ? "桥接方法:" : "普通方法:") + method.toGenericString());}}
}
打印结果:
桥接方法:public java.lang.Object com.joker.test.generic.Test3.get()
普通方法:public java.lang.Integer com.joker.test.generic.Test3.get()
桥接方法:public void com.joker.test.generic.Test3.set(java.lang.Object)
普通方法:public void com.joker.test.generic.Test3.set(java.lang.Integer)
以set方法作分析:
- 编译时,经过类型擦除后,TestInterface接的set方法变成了void set(Object t)
- 而实现类Test3原本的实现方法是void set(Integer s),明显已经不再是实现方法了
- 为了解决这个问题,Java编译器通过桥接的生成了一个**void set(Object t)**方法,保证了实现方法
2. 为何需要类型擦除
为什么Java不像C#一样实现真正的泛型呢?而要用类型擦除的方式实现了个伪泛型。
其实JDK1.5引入的泛型采用类型擦除式实现的根本原因是兼容性上的取舍,而不是因为实现不了真正意义上的泛型。
为了确保JDK1.5之前的和JDK1.5能使用同一个类加载器,所以Java通过类型擦除的方式实现的泛型支持。经过编译阶段的泛型类型擦除后,与JDK1.5之前是基本没有变动。
3. 类型信息并未完全擦除
下面举例说明:
定义一个Demo泛型类和一个Test测试类。
public class Demo<T> {private T id;public T getId() {return id;}
}
public class Test {public static void main(String[] args) {Demo<Integer> demo = new Demo<>();Integer id = demo.getId();}
}
1. 查看IDEA编译后的class文件
Demo.calss
public class Demo<T> {private T id;public Demo() {}public T getId() {return this.id;}
}
Test.class
public class Test {public Test() {}public static void main(String[] args) {Demo<Integer> demo = new Demo();Integer id = (Integer)demo.getId();}
}
从class文件可见:
- 使用泛型的地方进行了强制类型转换
- 但泛型的类型参数并未替换为Object
原因:在编译过程中,泛型信息是被擦除了,但是声明侧的泛型信息会被class文件以Signature的形式保留在Class文件的Constant pool中。
2. 使用javap命令反编译Demo.class文件和Test.class文件
javap -v Demo.class
Classfile /D:/work/my/springboot/target/classes/com/joker/test/generic/Demo.classLast modified 2023-2-14; size 610 bytesMD5 checksum 4851ec541c05f1d29bee93edb79085f0Compiled from "Demo.java"
public class com.joker.test.generic.Demo<T extends java.lang.Object> extends java.lang.Objectminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref #4.#24 // java/lang/Object."<init>":()V#2 = Fieldref #3.#25 // com/joker/test/generic/Demo.id:Ljava/lang/Object;#3 = Class #26 // com/joker/test/generic/Demo#4 = Class #27 // java/lang/Object#5 = Utf8 id#6 = Utf8 Ljava/lang/Object;#7 = Utf8 Signature#8 = Utf8 TT;#9 = Utf8 <init>#10 = Utf8 ()V#11 = Utf8 Code#12 = Utf8 LineNumberTable#13 = Utf8 LocalVariableTable#14 = Utf8 this#15 = Utf8 Lcom/joker/test/generic/Demo;#16 = Utf8 LocalVariableTypeTable#17 = Utf8 Lcom/joker/test/generic/Demo<TT;>;#18 = Utf8 getId#19 = Utf8 ()Ljava/lang/Object;#20 = Utf8 ()TT;#21 = Utf8 <T:Ljava/lang/Object;>Ljava/lang/Object;#22 = Utf8 SourceFile#23 = Utf8 Demo.java#24 = NameAndType #9:#10 // "<init>":()V#25 = NameAndType #5:#6 // id:Ljava/lang/Object;#26 = Utf8 com/joker/test/generic/Demo#27 = Utf8 java/lang/Object
{public com.joker.test.generic.Demo();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 7: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 this Lcom/joker/test/generic/Demo;LocalVariableTypeTable:Start Length Slot Name Signature0 5 0 this Lcom/joker/test/generic/Demo<TT;>;public T getId();descriptor: ()Ljava/lang/Object;flags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: getfield #2 // Field id:Ljava/lang/Object;4: areturnLineNumberTable:line 13: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 this Lcom/joker/test/generic/Demo;LocalVariableTypeTable:Start Length Slot Name Signature0 5 0 this Lcom/joker/test/generic/Demo<TT;>;Signature: #20 // ()TT;
}
Signature: #21 // <T:Ljava/lang/Object;>Ljava/lang/Object;
SourceFile: "Demo.java"
javap -v Test.class
Classfile /D:/work/my/springboot/target/classes/com/joker/test/generic/Test.classLast modified 2023-2-14; size 739 bytesMD5 checksum a82bd374c2bff99147acd130f3819415Compiled from "Test.java"
public class com.joker.test.generic.Testminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref #7.#28 // java/lang/Object."<init>":()V#2 = Class #29 // com/joker/test/generic/Demo#3 = Methodref #2.#28 // com/joker/test/generic/Demo."<init>":()V#4 = Methodref #2.#30 // com/joker/test/generic/Demo.getId:()Ljava/lang/Object;#5 = Class #31 // java/lang/Integer#6 = Class #32 // com/joker/test/generic/Test#7 = Class #33 // java/lang/Object#8 = Utf8 <init>#9 = Utf8 ()V#10 = Utf8 Code#11 = Utf8 LineNumberTable#12 = Utf8 LocalVariableTable#13 = Utf8 this#14 = Utf8 Lcom/joker/test/generic/Test;#15 = Utf8 main#16 = Utf8 ([Ljava/lang/String;)V#17 = Utf8 args#18 = Utf8 [Ljava/lang/String;#19 = Utf8 demo#20 = Utf8 Lcom/joker/test/generic/Demo;#21 = Utf8 id#22 = Utf8 Ljava/lang/Integer;#23 = Utf8 LocalVariableTypeTable#24 = Utf8 Lcom/joker/test/generic/Demo<Ljava/lang/Integer;>;#25 = Utf8 MethodParameters#26 = Utf8 SourceFile#27 = Utf8 Test.java#28 = NameAndType #8:#9 // "<init>":()V#29 = Utf8 com/joker/test/generic/Demo#30 = NameAndType #34:#35 // getId:()Ljava/lang/Object;#31 = Utf8 java/lang/Integer#32 = Utf8 com/joker/test/generic/Test#33 = Utf8 java/lang/Object#34 = Utf8 getId#35 = Utf8 ()Ljava/lang/Object;
{public com.joker.test.generic.Test();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 6: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 this Lcom/joker/test/generic/Test;public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=3, args_size=10: new #2 // class com/joker/test/generic/Demo3: dup4: invokespecial #3 // Method com/joker/test/generic/Demo."<init>":()V7: astore_18: aload_19: invokevirtual #4 // Method com/joker/test/generic/Demo.getId:()Ljava/lang/Object;12: checkcast #5 // class java/lang/Integer15: astore_216: returnLineNumberTable:line 9: 0line 10: 8line 11: 16LocalVariableTable:Start Length Slot Name Signature0 17 0 args [Ljava/lang/String;8 9 1 demo Lcom/joker/test/generic/Demo;16 1 2 id Ljava/lang/Integer;LocalVariableTypeTable:Start Length Slot Name Signature8 9 1 demo Lcom/joker/test/generic/Demo<Ljava/lang/Integer;>;MethodParameters:Name Flagsargs
}
SourceFile: "Test.java"
由反编译的文件可知:
- 声明侧的泛型被记录在Class文件的Constant pool中以Signature的形式保存
对于Java中泛型类型的获取可参考:Java中如何获取泛型类型信息
四、泛型使用
1. 泛型类
泛型类型用于类的定义中,被称为泛型类。用户在使用该类的时候,才把类型明确下来。
在类上定义的泛型,在实例方法中可以直接使用,不需要定义,但不能在静态方法中使用。
原因:Java中泛型只是一个占位符,必须在传递类型后才能使用。类实例化时才能正真的的传递类型参数,由于静态方法的加载先于类的实例化,也就是说类中的泛型还没有传递真正的类型参数静态的方法就已经加载完成了。
语法:
public class 类名<泛型表示符号> {
}
示例:
public class Test<T> {private T data;public T getData() {return data;}public void setData(T data) {this.data = data;}
}
如果使用时没指定具体的泛型类型,则泛型类型为Object。
public static void main(String[] args) {Test<String> test1 = new Test<>();String data1 = test1.getData();Test test2 = new Test();Object data2 = test2.getData();}
2. 泛型接口
泛型接口和泛型类的声明方式一致。泛型接口的具体类型需要在实现类中进行声明。
语法:
public interface 接口名<泛型标识符号> {
}
示例:
public interface TestInterface<T> {public T get();public void set(T t);
}
public class Test2 implements TestInterface<String> {@Overridepublic String get() {return null;}@Overridepublic void set(String s) {}
}
如果实现类未指定具体的泛型类型,则泛型类型为Object。
public class Test2 implements TestInterface{@Overridepublic Object get() {return null;}@Overridepublic void set(Object s) {}
}
3. 泛型方法
泛型类型声明在方法上,叫做泛型方法。
需要注意:只是在方法中使用类定义的泛型,该方法不是泛型方法。
语法:
public <泛型表示符号> void 方法名(泛型表示符号 参数名){
}public <泛型表示符号> 泛型表示符号 方法名(泛型表示符号 参数名){
}等......
示例:
public class Test {public static <T> void aaa(T t) {}public <T> void bbb(T t) {}
}
五、泛型扩展
1. 泛型的上下边界
泛型的上边界
泛型类型必须为指定类型的子类型。
格式:<? extends 类>
示例:
public class Test {public void aaa(List<? extends Number> t) {Number number = t.get(0);}public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);Test test = new Test();test.aaa(list);}
}
泛型的下边界
泛型类型必须为指定类型的父类型。
格式:<? super 类>
示例:
public class Test {public void aaa(List<? super Number> t) {Object object = t.get(0);}public static void main(String[] args) {ArrayList<Object> list = new ArrayList<>();list.add(1);Test test = new Test();test.aaa(list);}
}
2. 泛型中使用&(并且)操作符
- 当需要多重约束的时候,可以使用&操作符
- &操作符只能放在泛型的声明上(泛型类、泛型接口、方法方法的声明上)
- &操作符后面只能是接口,不能是具体的类型,即使是Object也不行
- &操作符不能用于super上 ,因为java有规定
使用方式:
// 泛型类上申明,约束泛型类变量class WildcardTypeT<T extends Comparable<T> & List<T> & Serializable> {}// 方法上申明public <R extends Enum<R> & Serializable> List<R> parse2Enums(){}
https://blog.csdn.net/tianzhonghaoqing/article/details/119705014
相关文章:
Java泛型
文章目录一、泛型介绍1. 背景2. 概念3. 好处二、泛型声明泛型类型符号泛型声明方式三、类型擦除1. 什么是类型擦除桥接方法2. 为何需要类型擦除3. 类型信息并未完全擦除四、泛型使用1. 泛型类2. 泛型接口3. 泛型方法五、泛型扩展1. 泛型的上下边界泛型的上边界泛型的下边界2. 泛…...
07 分布式事务Seata使用(2)
1、Seata是什么 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本的GTS&#x…...
c++练习题5
5.在C语言中,程序运行期间,其值不能被改变的量叫 常量 。 6.符号常量是指用一个符号名代表一个常量。 7.整型常量和浮点型常量也称为 数值常量 ,它们有正负之分。 9.在C中,变量是 其值可以改变的量 。 …...
Python 高级编程之正则表达式(八)
文章目录一、概述二、正则表达式语法1)字符匹配2)字符集合3)定位符4)分组1、定义分组2、引用分组3、命名分组三、Python 的 re 模块1)re.match() 方法2)re.search() 方法3)re.match() 与 re.sea…...
pynrrd常用操作解析
目录依赖安装官方文档常用操作1. 读部分nrrd.read()nrrd.read_header()nrrd.read_data()2. 写部分nrrd.write()依赖安装 pip install pynrrd官方文档 https://pynrrd.readthedocs.io/en/stable/ 常用操作 1. 读部分 nrrd.read() nrrdpath "your nrrd file path"…...
数据结构:链表基础OJ练习+带头双向循环链表的实现
目录 一.leetcode剑指 Offer II 027. 回文链表 1.问题描述 2.问题分析与求解 (1) 快慢指针法定位链表的中间节点 (2) 将链表后半部分进行反转 附:递归法反转链表 (3) 双指针法判断链表是否回文 二.带头双向循环链表的实现 1.头文件 2.节点内存申请接口和链表初始化接口…...
计算机视觉方向地理空间遥感图像数据集汇总
文章目录1.DSTL卫星图像数据集/Kaggle竞赛2.Swimming Pool and Car Detection/Kaggle竞赛3.SpaceNet Challenge 3数据集4.RarePlanes数据集5.BigEarthNet数据集6.NWPU VHR-10数据集7.UC Merced Land-Use数据集8.Inria Aerial Image Labeling数据集9.RSOD数据集1.DSTL卫星图像数…...
信息系统项目管理师真题精选(一)
1.信息系统的( )决定了系统可以被外部环境识别,外部环境或者其他系统可以按照预定的方法使用系统的功能或者影响系统的行为。A.可嵌套性B.稳定性C.开放性D.健壮性2、在实际的生产环境中,( )能使底层物理硬件…...
信息系统项目管理师刷题知识点(持续更新)
主要记录自己在备考高项过程中知识点 信息系统项目管理师刷题知识点(按刷题顺序排列) 1.信息技术应用是信息化体系六要素中的龙头,是国家信息化建设的主阵地,集中体现了国家信息化建设的需求和效益。 2.原型化方法也称为快速原型法…...
RabbitMq及其他消息队列
消息队列中间价都有哪些 先进先出 Kafka、Pulsar、RocketMQ、RabbitMQ、NSQ、ActiveMQ Rabbitmq架构 消费推拉模式 客户端消费者获取消息的方式,Kafka和RocketMQ是通过长轮询Pull的方式拉取消息,RabbitMQ、Pulsar、NSQ都是通过Push的方式。 pull类型…...
Toolformer: Language Models Can Teach Themselves to Use Tools
展示了LM可以通过简单的API教自己使用外部工具,并实现两个世界的最佳效果。我们介绍了Toolformer,这是一个经过训练的模型,可以决定调用哪些API,何时调用,传递哪些参数,以及如何将结果最好地纳入未来的标记…...
悲观锁与乐观锁
何谓悲观锁与乐观锁 乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。 悲观锁 总是假设最坏的情况,每次去拿数据…...
LeetCode 25. K 个一组翻转链表
原题链接 难度:hard\color{red}{hard}hard 题目描述 给你链表的头节点 headheadhead , kkk 个节点一组进行翻转,请你返回修改后的链表。 kkk 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 kkk 的整数倍…...
朗润国际期货招商:历次科技风头下巨头的博弈
历次科技风头下巨头的博弈 VR/AR、区块链、折叠屏、元宇宙、AIGC五轮科技风头下巨头们都进场了吗? VR/AR硬件 谷歌:2014年入局,推出AR眼镜 百度:未入局 京东:未入局 腾讯:传要开发 亚马逊࿱…...
配置中心Config
引入依赖<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.6.RELEASE</version></parent><properties><spring-cloud.version>Finchley.SR…...
【原创】java+jsp+servlet学生信息管理系统(jdbc+ajax+filter+cookie+分页)
一直想写一个比较基础的JavaWeb项目,然后综合各种技术,方便Java入门者进行学习。学生信息管理系统大家一般接触的比较多,那么就以这个为例来写一个基础项目吧。 需求分析: 使用jspservletmysql开发的学生信息管理系统࿰…...
链表题目总结 -- 回文链表
目录一. 从中心开始找最大的回文字符串1. 思路简述2. 代码3. 总结二. 判断是否为回文字符串1. 思路简述2. 代码3.总结三. 判断是否是回文链表1. 思路简述2. 代码3. 总结4. 优化解法一. 从中心开始找最大的回文字符串 题目链接:没有。给定一个字符串s,从…...
JAVA集合之List >> Arraylist/LinkedList/Vector结构
在Java开发过程中,可能经常会使用到List作为集合来使用,List是一个接口承于Collection的接口,表示着有序的列表。而我们要讨论的是它下面的实现类Arraylist/LinkedList/Vector的数据结构及区别。 ArrayList ArrayList:底层为数组…...
Linux多进程开发
一、进程概述 1、程序和进程 程序是包含一系列信息的文件,这些信息描述了如何在运行时创建一个进程: 二进制格式标识:每个程序文件都包含用于描述可执行文件格式的元信息。内核利用此信息来解释文件中的其他信息。(ELF可执行连…...
三维重建小有基础入门之特征点检测基础
前言:本文将从此篇开始,记录自己从普通CVer入门三维重建的学习过程,可能过程比较坎坷,都在摸索阶段,但争取每次学习都能进一步,提高自己的能力,同时,每篇文章都会按情况相应地推出B站…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
