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

一文带你深入理解【Java基础】· 泛型

写在前面


        Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误不足之处,请多多指正!谢谢大家!!!

        如果小哥哥小姐姐们对我的文章感兴趣,请不要吝啬你们的小手,多多点赞加关注呀!❤❤❤ 爱你们!!!


目录

写在前面

1. 为什么要有泛型

1.1 为什么要有泛型

1.2 泛型的概念

1.3 在集合中使用泛型

1.4 泛型代码演示

 2. 自定义泛型结构

2.1 泛型结构

2.2 泛型类、泛型接口

2.3 泛型方法

2.4 自定义泛型类型代码演示

2.5 泛型在继承上的体现

3. 通配符的使用

3.1 使用通配符

3.2 注意点

3.3 有限制的通配符

3.4 通配符代码演示

4. 泛型应用举例

4.1 泛型嵌套

4.2 实际案例

结语


【往期回顾】

一文带你深入理解【Java基础】· Java集合(上)

一文带你深入理解【Java基础】· 注解

一文带你深入理解【Java基础】· 枚举类

一文带你深入理解【Java基础】· 常用类(上)

一文带你深入理解【Java基础】· 多线程(上)

一文带你深入理解【Java基础】· 异常处理


1. 为什么要有泛型


1.1 为什么要有泛型

  • 泛型:标签
  • 举例:
    • 中药店,每个抽屉外面贴着标签
    • 超市购物架上很多瓶子,每个瓶子装的是什么,有标签
  • 泛型的设计背景
  • 集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以JDK1.5之前只能把元素类型设计为ObjectJDK1.5之后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型。Collection<E>List<E>ArrayList<E> 这个<E>就是类型参数,即泛型。

1.2 泛型的概念

  • 所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的类型参数,也称为类型实参)。
  • JDK1.5以后,Java引入了“参数化类型(Parameterized type)”的概念,允许我们在创建集合时再指定集合元素的类型,正如:List<String>,这表明该List只能保存字符串类型的对象。
  • JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,从而可以在声明集合变量、创建集合对象时传入类型实参。

那么为什么要有泛型呢,直接Object不是也可以存储数据吗?

1. 解决元素存储的安全性问题,好比商品、药品标签,不会弄错。
2. 解决获取数据元素时,需要类型强制转换的问题,好比不用每回拿商品、药品都要辨别。

 

Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮。

1.3 在集合中使用泛型

ArrayList<Integer> list = new ArrayList<>();//类型推断
list.add(78);
list.add(88);
list.add(77);
list.add(66);
//遍历方式一:
//for(Integer i : list) {//不需要强转//System.out.println(i);
//}
//遍历方式二:
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {System.out.println(iterator.next());
}
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("Tom1",34);
map.put("Tom2",44);
map.put("Tom3",33);
map.put("Tom4",32);
//添加失败
//map.put(33, "Tom");
Set<Entry<String,Integer>> entrySet = map.entrySet();
Iterator<Entry<String,Integer>> iterator = entrySet.iterator();
while(iterator.hasNext()) {Entry<String,Integer> entry = iterator.next();System.out.println(entry.getKey() + "--->" + entry.getValue());
}

1.4 泛型代码演示

import org.junit.Test;import java.util.*;/*** 泛型的使用* 1.jdk 5.0新增的特性** 2.在集合中使用泛型:*  总结:*  ① 集合接口或集合类在jdk5.0时都修改为带泛型的结构。*  ② 在实例化集合类时,可以指明具体的泛型类型*  ③ 指明完以后,在集合类或接口中凡是定义类或接口时,内部结构(比如:方法、构造器、属性等)使用到类的泛型的位置,都指定为实例化的泛型类型。*    比如:add(E e)  --->实例化以后:add(Integer e)*  ④ 注意点:泛型的类型必须是类,不能是基本数据类型。需要用到基本数据类型的位置,拿包装类替换*  ⑤ 如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型。** 3.如何自定义泛型结构:泛型类、泛型接口;泛型方法。见 GenericTest1.java*/
public class GenericTest {//在集合中使用泛型之前的情况:@Testpublic void test1() {ArrayList list = new ArrayList();//需求:存放学生的成绩list.add(78);list.add(76);list.add(89);list.add(88);//问题一:类型不安全//list.add("Tom");for (Object score : list) {//问题二:强转时,可能出现ClassCastExceptionint stuScore = (Integer) score;System.out.println(stuScore);}}//在集合中使用泛型的情况:以ArrayList为例@Testpublic void test2() {ArrayList<Integer> list = new ArrayList<Integer>();list.add(78);list.add(87);list.add(99);list.add(65);//编译时,就会进行类型检查,保证数据的安全
//        list.add("Tom");//方式一:
//        for(Integer score : list) {
//            //避免了强转操作
//            int stuScore = score;
//            System.out.println(stuScore);
//        }//方式二:Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()) {int stuScore = iterator.next();System.out.println(stuScore);}}//在集合中使用泛型的情况:以HashMap为例@Testpublic void test3() {//Map<String,Integer> map = new HashMap<String,Integer>();//jdk7新特性:类型推断Map<String, Integer> map = new HashMap<>();map.put("Tom", 87);map.put("Jerry", 87);map.put("Jack", 67);//      map.put(123,"ABC");//泛型的嵌套Set<Map.Entry<String, Integer>> entry = map.entrySet();Iterator<Map.Entry<String, Integer>> iterator = entry.iterator();while (iterator.hasNext()) {Map.Entry<String, Integer> e = iterator.next();String key = e.getKey();Integer value = e.getValue();System.out.println(key + "----" + value);}}
}

 2. 自定义泛型结构


2.1 泛型结构

1.泛型的声明
  • interface List<T> class GenTest<K,V>
  • 其中,T,K,V不代表值,而是表示类型。这里使用任意字母都可以。
  • 常用T表示,是Type的缩写。
2.泛型的实例化:
  • 一定要在类名后面指定类型参数的值(类型)。如:
    • List<String> strList = new ArrayList<String>();
    • Iterator<Customer> iterator = customers.iterator();
  • T只能是类,不能用基本数据类型填充。但可以使用包装类填充
  • 把一个集合中的内容限制为一个特定的数据类型,这就是generics背后的核心思想
  •  体会:使用泛型的主要优点是能够在编译时而不是在运行时检测错误。

2.2 泛型类、泛型接口

1. 泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:<E1,E2,E3>
2. 泛型类的构造器如下:public GenericClass(){}
    而下面是错误的:public GenericClass<E>(){}
3. 实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致。
4. 泛型不同的引用不能相互赋值。尽管在编译时ArrayList<String>ArrayList<Integer>是两种类型,但是,在运行时只有一个ArrayList被加载到JVM中。
5. 泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价于Object经验:泛型要使用一路都用。要不用,一路都不要用。
6. 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
7. jdk1.7,泛型的简化操作:ArrayList<Fruit> flist = new ArrayList<>();
8. 泛型的指定中不能使用基本数据类型,可以使用包装类替换。
9. 在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在静态方法中不能使用类的泛型。
10. 异常类不能是泛型的
11. 不能使用new E[]。但是可以:E[] elements = (E[])new Object[capacity];
参考:ArrayList源码中声明:Object[] elementData,而非泛型参数类型数组。
12.父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型:
  • 子类不保留父类的泛型:按需实现
    • 没有类型 擦除
    • 具体类型
  • 子类保留父类的泛型:泛型子类
    • 全部保留
    • 部分保留
结论:子类必须是“富二代”,子类除了指定或保留父类的泛型,还可以增加自己的泛型
class Father<T1, T2> {
}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son<A, B> extends Father {//等价于class Son extends Father<Object,Object> {
}
// 2)具体类型
class Son2<A, B> extends Father<Integer, String> {
}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2, A, B> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2, A, B> extends Father<Integer, T2> {
}    
class Person<T> {// 使用T类型定义变量private T info;// 使用T类型定义一般方法public T getInfo() {return info;
}
public void setInfo(T info) {this.info = info;
}
// 使用T类型定义构造器
public Person() {
}
public Person(T info) {this.info = info;
}
// static的方法中不能声明泛型
//public static void show(T t) {
//
//}
// 不能在try-catch中使用泛型定义
//public void test() {
//try {
//
//} catch (MyException<T> ex) {
//
//}
//}
//}


2.3 泛型方法

  • 方法,也可以被泛型化,不管此时定义在其中的类是不是泛型类。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。
泛型方法的格式:
  • [访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常
  • 泛型方法声明泛型时也可以指定上限(12.5中讲)
public class DAO {public <E> E get(int id, E e) {E result = null;return result;}
}
public static <T> void fromArrayToCollection(T[] a, Collection<T> c) {for (T o : a) {c.add(o);}
}
public static void main(String[] args) {Object[] ao = new Object[100];Collection<Object> co = new ArrayList<Object>();fromArrayToCollection(ao, co);String[] sa = new String[20];Collection<String> cs = new ArrayList<>();fromArrayToCollection(sa, cs);Collection<Double> cd = new ArrayList<>();// 下面代码中T是Double类,但sa是String类型,编译错误。// fromArrayToCollection(sa, cd);// 下面代码中T是Object类型,sa是String类型,可以赋值成功。fromArrayToCollection(sa, co);
}
class Creature{}
class Person extends Creature{}
class Man extends Person{}
class PersonTest {public static <T extends Person> void test(T t) {System.out.println(t);}public static void main(String[] args) {test(new Person());test(new Man());//The method test(T) in the type PersonTest is not //applicable for the arguments (Creature)test(new Creature());}
}

2.4 自定义泛型类型代码演示

import org.junit.Test;import java.util.ArrayList;
import java.util.List;/** 如何自定义泛型结构:泛型类、泛型接口;泛型方法。** 1. 关于自定义泛型类、泛型接口:*/
public class GenericTest1 {@Testpublic void test1() {//如果定义了泛型类,实例化没有指明类的泛型,则认为此泛型类型为Object类型//要求:如果大家定义了类是带泛型的,建议在实例化时要指明类的泛型。Order order = new Order();order.setOrderT(123);order.setOrderT("ABC");//建议:实例化时指明类的泛型Order<String> order1 = new Order<String>("orderAA", 1001, "order:AA");order1.setOrderT("AA:hello");}@Testpublic void test2() {SubOrder sub1 = new SubOrder();//由于子类在继承带泛型的父类时,指明了泛型类型。则实例化子类对象时,不再需要指明泛型。sub1.setOrderT(1122);SubOrder1<String> sub2 = new SubOrder1<>();sub2.setOrderT("order2...");}@Testpublic void test3() {ArrayList<String> list1 = null;ArrayList<Integer> list2 = new ArrayList<Integer>();//泛型不同的引用不能相互赋值。//list1 = list2;Person p1 = null;Person p2 = null;p1 = p2;}//测试泛型方法@Testpublic void test4() {Order<String> order = new Order<>();Integer[] arr = new Integer[]{1, 2, 3, 4};//泛型方法在调用时,指明泛型参数的类型。List<Integer> list = order.copyFromArrayToList(arr);System.out.println(list);}
}
import java.util.ArrayList;
import java.util.List;/*** 自定义泛型类*/
public class Order<T> {String orderName;int orderId;//类的内部结构就可以使用类的泛型T orderT;public Order() {//编译不通过//T[] arr = new T[10];//编译通过T[] arr = (T[]) new Object[10];}public Order(String orderName, int orderId, T orderT) {this.orderName = orderName;this.orderId = orderId;this.orderT = orderT;}//如下的三个方法都不是泛型方法public T getOrderT() {return orderT;}public void setOrderT(T orderT) {this.orderT = orderT;}@Overridepublic String toString() {return "Order{" +"orderName='" + orderName + '\'' +", orderId=" + orderId +", orderT=" + orderT +'}';}
//    静态方法中不能使用类的泛型。
//    public static void show(T orderT) {
//        System.out.println(orderT);
//    }public void show() {//编译不通过
//        try{
//
//        } catch(T t) {
//
//        }}//泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系。//换句话说,泛型方法所属的类是不是泛型类都没有关系。//泛型方法,可以声明为静态的。原因:泛型参数是在调用方法时确定的。并非在实例化类时确定。public static <E> List<E> copyFromArrayToList(E[] arr) {ArrayList<E> list = new ArrayList<>();for (E e : arr) {list.add(e);}return list;}
}
import java.util.ArrayList;
import java.util.List;public class SubOrder extends Order<Integer> {//SubOrder:不是泛型类public static <E> List<E> copyFromArrayToList(E[] arr) {ArrayList<E> list = new ArrayList<>();for (E e : arr) {list.add(e);}return list;}
}
public class SubOrder1<T> extends Order<T> {//SubOrder1<T>:仍然是泛型类
}

2.5 泛型在继承上的体现

  • 如果BA的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G<B>并不是G<A>的子类型!
  • 比如:StringObject的子类,但是List<String >并不是List<Object>的子类。
public void testGenericAndSubClass() {Person[] persons = null;Man[] mans = null;// 而 Person[] 是 Man[] 的父类.persons = mans;Person p = mans[0];// 在泛型的集合上List<Person> personList = null;List<Man> manList = null;// personList = manList;(报错)
}

3. 通配符的使用


3.1 使用通配符

1.使用类型通配符:?

  • 比如:List<?> Map<?,?>
  • List<?>List<String>List<Object>等各种泛型List的父类。

2.读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object

3.写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中添加对象。

  • 唯一的例外是null,它是所有类型的成员。

将任意元素加入到其中不是类型安全的

  • Collection<?> c = new ArrayList<String>();
  • c.add(new Object()); // 编译时错误
  • 因为我们不知道c的元素类型,我们不能向其中添加对象。add方法有类型参数E作为集合的元素类型。我们传给add的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。

唯一的例外的是null,它是所有类型的成员。

另一方面,我们可以调用get()方法并使用其返回值。返回值是一个未知的类型,但是我们知道,它总是一个Object

public static void main(String[] args) {List<?> list = null;list = new ArrayList<String>();list = new ArrayList<Double>();// list.add(3);//编译不通过list.add(null);List<String> l1 = new ArrayList<String>();List<Integer> l2 = new ArrayList<Integer>();l1.add("尚硅谷");l2.add(15);read(l1);read(l2);
}
public static void read(List<?> list) {for (Object o : list) {System.out.println(o);}
}

3.2 注意点

注意点1:编译错误:不能用在泛型方法声明上,返回值类型前面<>不能使用?
public static <?> void test(ArrayList<?> list) {
}
注意点2:编译错误:不能用在泛型类的声明上
class GenericTypeClass<?> {
}
注意点3:编译错误:不能用在创建对象上,右边属于创建集合对象
ArrayList<?> list2 = new ArrayList<?>();

3.3 有限制的通配符

<?>
  • 允许所有泛型的引用调用
通配符指定上限
  • 上限extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<=
通配符指定下限
  • 下限super:使用时指定的类型不能小于操作的类,即>=
举例:
<? extends Number> (无穷小 , Number]
  • 只允许泛型为NumberNumber子类的引用调用
<? super Number> [Number , 无穷大)
  • 只允许泛型为NumberNumber父类的引用调用
<? extends Comparable>
  • 只允许泛型为实现Comparable接口的实现类的引用调用
public static void printCollection3(Collection<? extends Person> coll) {//Iterator只能用Iterator<?>或Iterator<? extends Person>.why?Iterator<?> iterator = coll.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}
}
public static void printCollection4(Collection<? super Person> coll) {//Iterator只能用Iterator<?>或Iterator<? super Person>.why?Iterator<?> iterator = coll.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}
}

3.4 通配符代码演示

import org.junit.Test;import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*** 1. 泛型在继承方面的体现* 2. 通配符的使用*/
public class GenericTest {/*1. 泛型在继承方面的体现虽然类A是类B的父类,但是G<A> 和G<B>二者不具备子父类关系,二者是并列关系。补充:类A是类B的父类,A<G> 是 B<G> 的父类*/@Testpublic void test1() {Object obj = null;String str = null;obj = str;Object[] arr1 = null;String[] arr2 = null;arr1 = arr2;
//      编译不通过
//      Date date = new Date();
//      str = date;List<Object> list1 = null;List<String> list2 = new ArrayList<String>();//此时的list1和list2的类型不具有子父类关系//编译不通过//list1 = list2;/*反证法:假设list1 = list2;list1.add(123);导致混入非String的数据。出错。*/show(list1);show1(list2);}public void show1(List<String> list) {}public void show(List<Object> list) {}@Testpublic void test2() {AbstractList<String> list1 = null;List<String> list2 = null;ArrayList<String> list3 = null;list1 = list3;list2 = list3;List<String> list4 = new ArrayList<>();}/*2. 通配符的使用通配符:?类A是类B的父类,G<A>和G<B>是没有关系的,二者共同的父类是:G<?>*/@Testpublic void test3() {List<Object> list1 = null;List<String> list2 = null;List<?> list = null;list = list1;list = list2;//编译通过//print(list1);//print(list2);List<String> list3 = new ArrayList<>();list3.add("AA");list3.add("BB");list3.add("CC");list = list3;//添加(写入):对于List<?>就不能向其内部添加数据。//除了添加null之外。//list.add("DD");//list.add('?');list.add(null);//获取(读取):允许读取数据,读取的数据类型为Object。Object o = list.get(0);System.out.println(o);}public void print(List<?> list) {Iterator<?> iterator = list.iterator();while (iterator.hasNext()) {Object obj = iterator.next();System.out.println(obj);}}/*3.有限制条件的通配符的使用。? extends A:G<? extends A> 可以作为G<A>和G<B>的父类,其中B是A的子类? super A:G<? super A> 可以作为G<A>和G<B>的父类,其中B是A的父类*/@Testpublic void test4() {List<? extends Person> list1 = null;List<? super Person> list2 = null;List<Student> list3 = new ArrayList<Student>();List<Person> list4 = new ArrayList<Person>();List<Object> list5 = new ArrayList<Object>();list1 = list3;list1 = list4;//list1 = list5;//list2 = list3;list2 = list4;list2 = list5;//读取数据:list1 = list3;Person p = list1.get(0);//编译不通过//Student s = list1.get(0);list2 = list4;Object obj = list2.get(0);//编译不通过//Person obj = list2.get(0);//写入数据://编译不通过//list1.add(new Student());//编译通过list2.add(new Person());list2.add(new Student());}
}

4. 泛型应用举例


4.1 泛型嵌套

public static void main(String[] args) {HashMap<String, ArrayList<Citizen>> map = new HashMap<String, ArrayList<Citizen>>();ArrayList<Citizen> list = new ArrayList<Citizen>();list.add(new Citizen("刘恺威"));list.add(new Citizen("杨幂"));list.add(new Citizen("小糯米"));map.put("刘恺威", list);Set<Entry<String, ArrayList<Citizen>>> entrySet = map.entrySet();Iterator<Entry<String, ArrayList<Citizen>>> iterator = entrySet.iterator();while (iterator.hasNext()) {Entry<String, ArrayList<Citizen>> entry = iterator.next();String key = entry.getKey();ArrayList<Citizen> value = entry.getValue();System.out.println("户主:" + key);System.out.println("家庭成员:" + value);}
}

4.2 实际案例

用户在设计类的时候往往会使用类的关联关系,例如,一个人中可以定义一个信息的属性,但是一个人可能有各种各样的信息(如联系方式、基本信息等),所以此信息属性的类型就可以通过泛型进行声明,然后只要设计相应的信息类即可。


结语


本人会持续更新文章的哦!希望大家一键三连,你们的鼓励就是作者不断更新的动力

相关文章:

FPGA笔记[2]-拨码开关控制LED灯

使用四个拨码开关的异或逻辑亮灯控制LED灯亮灭.摘要 使用四个拨码开关的异或逻辑亮灯控制LED灯亮灭. 关键信息系统macOS 14.4.1,Apple Silicon M2 开发板:Sipeed-Tang-Primer-20k FPGA芯片:GW2A-LV18PG256C8/I7(GW2A-18C-PBGA256) 工具链:YosysHQ/oss-cad-suite原理简介 LUT4简…...

[20240516]建立任意进制转10进制脚本xto10.sql脚本.txt

[20240516]建立任意进制转10进制脚本xto10.sql脚本.txt--//bash shell 64进制编码从0开始. 0-9 , a-z , A-Z.这样仅仅62个编码.还剩下2个.@_--//这样完整的编码如下:$ base64=$(echo {0..9} {a..z} {A..Z} @ _)$ echo $base640 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n …...

Nginx 支持 CORS

Nginx 支持 CORS 先说下最终增加的配置: add_header Access-Control-Allow-Origin https://a.domain.com always; add_header Access-Control-Allow-Headers content-type,authorization; add_header Access-Control-Max-Age 3600; if ($request_method = OPTIONS) {return 20…...

delphi安卓动态权限申请

delphi安卓动态权限申请delphi安卓动态权限申请 安卓8及以上版本,除了原来的静态权限申请以外,还需要动态权限申请。 delphi10.3开始支持安卓动态权限申请。 delphi11开始官方改变了安卓动态权限申请的参数类型,导致原来编写的代码,编码报错。 下面的代码,可以很好地解决权…...

说说JavaScript中的事件模型

一、事件与事件流 javascript中的事件,可以理解就是在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件、鼠标事件、自定义事件等 由于DOM是一个树结构,如果在父子节点绑定事件时候,当触发子节点的时候,就存在一个顺序问题,这就涉及到了事…...

linux IPIP封装 抓包方式

单项抓包tcpdump -nn -e -i eth0 "ip proto 4 and (ip[20+16:1]=10 and ip[20+17:1]=244 and ip[20+18:1]=72 and ip[20+19:1]=10)"双向抓包tcpdump -nn -e -i eth1 "ip proto 4 and ((ip[20+12:1]=10 and ip[20+13:1]=244 and ip[20+14:1]=72 and ip[20+15:1]=…...

一文带你深入理解【Java基础】· 泛型

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…...

RabbitMQ学习笔记

目录 尚硅谷mq视频学习笔记 1.1. MQ 的相关概念 1.1.1. 什么是MQ 1.1.2. 为什么要用MQ 1.1.3. MQ 的分类 1.ActiveMQ 2.Kafka 3.RocketMQ 4.RabbitMQ 1.1.4. MQ 的选择 1.Kafka 2.RocketMQ 3.RabbitMQ 1.2. RabbitMQ 1.2.1. RabbitMQ 的概念 1.2.2. 四大核心概念…...

Java安全-CC1

CC1 这里用的是组长的链子和yso好像不太一样&#xff0c;不过大体上都是差不多的。后半条的链子都是一样的&#xff0c;而且这条更短更易理解。yso的CC1过段时间再看一下。 环境 Maven依赖&#xff1a; <dependencies><dependency><groupId>commons-colle…...

【得到日期对象NSDate的各个部分 Objective-C语言】

一、得到日期对象NSDate的各个部分,年月日时分秒 1.例如,我这儿有1个NSDate对象, NSDate *date = [NSDate date]; 这个日期里面是不是有年、有月、有日、有时、有分、有秒 我想单独的拿到这个日期里面的年,该怎么拿 用date.year属性,行吗,不行,因为没有这个属性 用…...

前端面试常考 | CSS垂直居中解决方案

文章目录一. 前言二. flx布局实现三. Grid布局实现四. 绝对定位transform五. 绝对定位负margin五. 绝对定位calc六. 定位加margin一. 前言 前段时间刷到一篇帖子&#xff0c;说面试竟然遇到了CSS的考点&#xff0c;让回答CSS实现垂直居中的方式有哪些?&#xff0c;都2022年了…...

Flink中的UDF的实现

Flink 的 Table API 和 SQL 提供了多种自定义函数的接口&#xff0c;以抽象类的形式定义。当前 UDF 主要有以下几类&#xff1a; 标量函数&#xff08;Scalar Functions&#xff09;&#xff1a;将输入的标量值转换成一个新的标量值&#xff1b;表函数&#xff08;Table Funct…...

Linux教程

Linux 目录结构 /bin&#xff1a;&#xff08;binary&#xff09;存放的是一些二进制文件&#xff0c;但是在Linux中二进制文件是可以被执行的。这个目录中的命令文件是给普通用户使用&#xff08;非超级管理员用户&#xff09;。 /etc&#xff1a;Linux下所有的配置文件都会…...

1.3 Apache Hadoop的重要组成-hadoop-最全最完整的保姆级的java大数据学习资料

文章目录1.3 Apache Hadoop的重要组成1.3 Apache Hadoop的重要组成 HadoopHDFS(分布式文件系统)MapReduce(分布式计算框架)Yarn(资源协调框架)Common模块 Hadoop HDFS&#xff1a;&#xff08;Hadoop Distribute File System &#xff09;一个高可靠、高吞吐量的分布式文件系统…...

【蓝桥杯】第十四届模拟赛第一期及第二期填空汇总

目录 1.A题&#xff08;进制位数&#xff09; 位运算符 第一期 问题描述 解析 第二期 解析 代码 2.B题&#xff08;日期问题&#xff09; 第一期 问题描述 解析 代码实现 执行结果 第二期 问题描述 解析 3.C题&#xff08;数学问题&#xff09; 第一期 问题…...

Go学习之路-环境搭建

默认运行设备系统&#xff1a;MacOS 安装 安装包下载地址&#xff08;下面3个都可以&#xff09;&#xff1a; https://studygolang.com/dl https://golang.google.cn/dl/ https://golang.org/dl/ 我这里选择 pkg包、一键安装、默认的安装路径 /usr/local/go 环境 设置go语言…...

Siamese Neural Network (SNN: 孪生神经网络)

【学习参考】&#xff1a; https://blog.csdn.net/MyArrow/article/details/122539749https://blog.csdn.net/MyArrow/article/details/122539749 Siamese network 孪生神经网络--一个简单神奇的结构 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/35040994 【Siamese和Ch…...

22个每个程序员都应该知道的 Git 命令

在这篇文章中&#xff0c;我写了一个快速学习 git 命令的备忘单。它将包括开发人员每天使用的命令&#xff0c;如 git add、git commit、git pull、git fetch&#xff0c;并共享其他有用的 git 命令。 我一直使用Git的一些命令&#xff0c;今天这个列表清单&#xff0c;希望也…...

Android动画——使用动画启动Activity

1、使用动画启动Activity概述 我们在Android开发应用时&#xff0c;会遇到一个页面跳转到另一个页面的情况&#xff0c;这时候我们如果使用动画过渡会使得页面更加的流畅。这是一个滑动式的进入和退出的动画可以看到Android的过渡动画可以在不同状态之间建立视觉联系。您可以为…...

【YOLO系列改进NO.46】改进激活函数为ACON

文章目录 前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv7,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点对YOLOv7的如何改进进行详细…...

JavaScript -- 09. 内置对象的介绍

文章目录内置对象1 解构赋值1.1 保留默认值1.2 接受剩余的所有参数1.3 对函数执行结果解构1.4 交换两个变量的值1.5 二维数组结构2 对象的解构2.1 声明对象同时解构对象2.2 先声明再解构2.3 解构不存在的属性2.4 设置解构别名2.5 设置解构默认值3 对象的序列化3.1 对象的序列化…...

Spring核心与设计思想

⭐️前言⭐️ 这篇文章作为Spring篇目的开篇&#xff0c;带领大家认识Spring&#xff0c;知道为什么要用Spring框架&#xff0c;以及了解Spring的核心与设计思想。 &#x1f349;博客主页&#xff1a; &#x1f341;【如风暖阳】&#x1f341; &#x1f349;精品Java专栏【Jav…...

Java的字符串String

文章目录什么是字符串String类的声明为什么我们的String是不可变的为什么String类用final修饰String的创建字符串比较相等关于Java中的比较关于字符串不同赋值操作对应的内存分配那对象如何进行比较内容字符串常量池StringTalbe的位置字符串常见的操作拼接操作获得字符串的子串…...

net-java-php-python-网络安全教育学习网站计算机毕业设计程序

net-java-php-python-网络安全教育学习网站计算机毕业设计程序 net-java-php-python-网络安全教育学习网站计算机毕业设计程序本源码技术栈&#xff1a; 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 开发软件&#xff1a;idea eclipse 前端技术&#xff1a;…...

git分支详解——记住这些指令能帮助你解决大部分git的分支问题

Github 之 分支 branch 操作之 查看分支/创建分支/切换分支/提交分支/删除分支/合并分支 等操作 一、简单介绍 二、查看分支 1、查看本地所有分支&#xff1a;git branch 2、查看远程有哪些分支&#xff1a;git branch -r 3、查看所有分支&#xff08;本地和远程的&#xff09;…...

jdk11新特性——JShell交互性工具

目录一、jshell概述二、jshell位置三、jshell示例3.1、示例一&#xff08;声明变量并赋值&#xff09;3.2、示例二&#xff08;输出打印内容&#xff09;3.3、示例三&#xff08;帮助命令&#xff09;一、jshell概述 java9引入了jshell这个交互性工具&#xff0c;让Java也可以…...

Git全套,从简到细

Git DravenGit一、git工具引入二、git本地工具2.1、下载2.2、使用2.3、修改2.4、查看历史版本2.5、回退历史版本2.6、起死回生三、git远程仓库3.1、使用gitee3.2、配置本地仓库参数3.3、查看gitee仓库3.4、修改后推送四、git两人协作-非冲突小智小杨五、git两人协作-冲突六、gi…...

【分布式能源的选址与定容】基于非支配排序多目标遗传优化算法求解分布式能源的选址与定容(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…...

基于PHP+MySQL托管中心管理系统的设计与实现

随着在校学生人数的不断增加,学生的数量也在不断的增加,但是很多时候因为父母工作忙没时间,以及一些其他的原因没办法对学生间辅导,这就诞生了托管中心这一行业,但是传统的托管中心多是人工手动的模式进行管理的,这很不科学也不合理,为了改变这一现状,我们开发了托管中心管理系…...

【算法】排序——直接排序

内部排序的全部过程都是在内存中进行的。按排序策略的不同可以将内部排序划分为直接插入排序、冒泡排序、简单选择排序、希尔排序、快速排序、堆排序、归并排序、基数排序等。其中前三种排序方法属于简单的排序方法&#xff0c;其特点是排序过程直观、易于理解和实现&#xff0…...

华为高级技术专家多年经验分享微服务治理体系、架构及实践文档

前言 都说程序员工资高、待遇好&#xff0c; 2022 金九银十到了&#xff0c;你的小目标是 30K、40K&#xff0c;还是 16薪的 20K&#xff1f;作为一名 Java 开发工程师&#xff0c;当能力可以满足公司业务需求时&#xff0c;拿到超预期的 Offer 并不算难。然而&#xff0c;提升…...

HTML+CSS网页设计期末课程大作业 【茶叶文化网站设计题材】web前端开发技术 web课程设计 网页规划与设计

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…...

数据结构与算法(六) 贪心算法

这篇文章来讲贪心算法&#xff08;Greedy Algorithm&#xff09;&#xff0c;这是一种特殊的动态规划算法 1、本质 我们在之前的文章中讲过&#xff0c;动态规划可以解决一类具有最优子结构和重叠子问题特征的问题 贪心算法本质上是一种特殊的动态规划算法&#xff0c;因此在…...

LeetCode-1774. 最接近目标价格的甜点成本【数组,背包问题,优化暴力,回溯】

LeetCode-1774. 最接近目标价格的甜点成本【数组&#xff0c;背包问题&#xff0c;优化暴力&#xff0c;回溯】题目描述&#xff1a;解题思路一&#xff1a;转化为0-1背包求解。一&#xff1a;因为每种配料最多可以用两次&#xff0c;所以直接把每种辅料变成两个。二&#xff1…...

Python封装机制及实现方法

大部分语言都具备 3 个典型特征&#xff0c;即封装、继承和多态。 简单的理解封装&#xff08;Encapsulation&#xff09;&#xff0c;即在设计类时&#xff0c;刻意地将一些属性和方法隐藏在类的内部&#xff0c;这样在使用此类时&#xff0c;将无法直接以“类对象.属性名”&…...

Flet 教程大全合集

Flet是什么 Flet 是一个框架,使您能够轻松地以您喜欢的语言构建实时 Web、移动和桌面应用程序,并与您的团队安全地共享它们。无需前端经验。 Flet有什么优势 Flet有什么特点 在几分钟内从想法到应用程序 用于您的团队、周末项目、数据输入表单、信息亭应用程序或高保真原型…...

mongodb整合springbootQ

SpringBoot整合MongoDB_一个冬天的童话的博客-CSDN博客_mongodb的依赖SpringBoot整合MongoDB的过程https://blog.csdn.net/m0_53563908/article/details/1268980981&#xff0c;环境配置 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId&g…...

【吴恩达机器学习笔记】十一、聚类

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为学习吴恩达机器学习视频的同学提供的随堂笔记。 &#x1f4da;专栏简介&#xff1a;在这个专栏&#xff0c;我将整理吴恩达机器学习视频的所有内容的笔记&…...

BUUCTF Misc 黑客帝国 [MRCTF2020]你能看懂音符吗 [HBNIS2018]caesar [HBNIS2018]低个头

黑客帝国 下载文件 一长串16进制&#xff0c;复制到在线16进制转文本 很明显是一个RAR文件&#xff0c;使用脚本将16进制转换成文件 import binasciihex_data这里填十六进制数据 outopen(res.rar,wb) out.write(binascii.unhexlify(hex_data)) out.close() 需要密码&#xff…...

基于多目标灰狼算法的冷热电联供型微网低碳经济调度(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…...

Linux系统启动过程总结

Linux系统启动过程总结 1、Linux 中 rc.local、init.d、rc.x、init 这几个文件(夹)各有什么作用?启动执行的脚本应该均放在 rc.local 中吗? - 知乎 2、/etc/inittab文件详解_muxi01lingyi的博客-CSDN博客_/etc/inittab /etc/inittab文件详解 - 莘莘学子 - 博客园 3、Li…...

防火墙ssh详解讲解

♥️作者&#xff1a;小刘在C站\ ♥️每天分享云计算网络运维课堂笔记&#xff0c;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放。 目录 一.防火墙配置对外的默认 二.防火墙配置内部ospf 三.防火墙远程管理 四.远程管理…...

Java【String】【StringBuilder】【StringBuffer】你都会用吗

文章目录前言一、常用的方法1、字符串构造2、字符串比较3、字符串查找4、字符串转化5、字符串替换6、字符串分割7、字符串截取二、字符串的不可变性三、StringBuilder、StringBuffer总结前言 在校招和笔试过程中&#xff0c;字符串是相当频繁被问到的话题&#xff0c;在之前的…...

Himall商城Xml帮助类 XML序列化 OSS策略

#region XML序列化 OSS策略 /// <summary> /// XML序列化 /// </summary> /// <param name="obj">序列对象</param> /// <param name="filePath">XML文件路径</param> /// …...

【人民币识别】人民币序列号识别【含GUI Matlab源码 908期】

⛄一、简介 本文描述的人民币序列号识别系统实现了从图像预处理到识别结果的过程, 而序列号识别是本文的重要内容.以序列号区域为研究对象, 主要包括图像预处理、图像分割以及序列号识别等过程。 1 图像预处理 人民币图像总体上来说灰度偏高, 灰度值基本上都大于150 (对8位25…...

html静态网站基于动漫网站网页设计与实现共计4个页面

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 ⚽精彩专栏推荐&#x1…...

Himall商城Zip帮助类压缩文件(Zip)

public class ZipInfo { /// <summary> /// 解/压缩成功状态 /// </summary> public bool Success { get; set; } /// <summary> /// 解/压缩结果信息 /// <…...

MyBatis-Plus条件构造器[常用的模糊查询、排序查询、逻辑查询和指定字段查询案例]

系列文章目录 Mybatis-Plus知识点[MyBatisMyBatis-Plus的基础运用]_心态还需努力呀的博客-CSDN博客 Mybatis-PlusSpringBoot结合运用_心态还需努力呀的博客-CSDN博客MyBaits-Plus中TableField和TableId用法_心态还需努力呀的博客-CSDN博客 MyBatis-Plus中的更新操作&#x…...

cubeIDE开发, 如何结合FreeRTOS开发STM32程序

一、STM32CubeIDE使用内置的FreeRTOS 不同于STM32CubeIDE使用像RTThread这些第三方物联网系统&#xff0c;STM32CubeIDE在安装时就已经在MiddleWare中间件一栏直接支持了FreeRTOS操作系统。 既然STM32CubeIDE已经把FreeRTOS深度整合到了自家的系统中&#xff0c;所以移植及使用…...

写给儿子的一封信

最近听闻你成绩有点不理想&#xff0c;爸爸想跟你讲几个想法。 之前学羽毛球的时候&#xff0c;我往往带有期望&#xff0c;希望你能学成像林丹一样。每次你去上课&#xff0c;我也在旁边盯着&#xff0c;后来我发现效果不好&#xff0c;你好像很害怕我说你&#xff0c;学的也不…...

eclipse导入svn项目,项目有红色的感叹号/叉号

eclipse导入svn项目&#xff0c;项目左下角有红色的感叹号/叉号 1.首先调出Problems ( window -> show view-> Problems ) 查看报错信息 其次&#xff0c;看看Project是否开启了项目自动构建&#xff08;Build Automatically&#xff09; 2.根据报错信息逐一解决 3.…...

基于 Serverless 架构的 CI/CD 框架:Serverless-cd

近日&#xff0c;Serverless 开发者平台 Serverless Devs 重磅发布基于 Serverless 架构的轻量级 CI/CD 框架 ——Serverless-cd。Serverless-cd 是一款运行在 Serverless 架构上的功能强大而灵活&#xff0c;安全&#xff0c;低成本的 CI/CD 开源框架。该框架基于 Serverless …...

Vue Class与Style绑定

Vue Class与Style绑定1 Class绑定1.1 字符串写法1.2 数组写法1.3 对象写法2 Style绑定2.1 对象写法2.2 数组写法1 Class绑定 在Vue中&#xff0c;如果要为某个元素动态添加某个类&#xff0c;并不会使用document.getElementById等选择器将该元素获得&#xff0c;而是使用v-bin…...

制作一个谷歌浏览器插件,实现网页数据爬虫

一、什么是浏览器插件 浏览器插件&#xff0c;基于浏览器的原有功能&#xff0c;另外增加新功能的工具&#xff0c;是可定制浏览体验的小型软件程序&#xff0c;让用户可以根据个人需要或偏好来定制浏览器。 如拦截网页中的广告、划词翻译、倍速视频等等。 Chrome、edge等浏…...

Java实验七

文章目录前言一、判断E盘指定目录下是否有后缀名为.jpg的文件&#xff0c;如果有就输出此文件名称。二、分别使用字节流和字节缓冲流的两种读取方式实现对图片文件的复制操作并比较两种方式在复制时间上的效率。三、编写一个程序&#xff0c;分别使用转换流、字符流和缓冲字符流…...

Linux文件系统——文件系统、挂载点、目录结构

目录 一、目录结构 1.1 基本介绍 1.2 详细说明目录作用 二、挂载点 一、目录结构 1.1 基本介绍 Linux是一切皆文件&#xff0c;将所用的东西当做文件处理 目录结构就是一个单一的树状结构 整个的目录树只有一个树根&#xff1a;/ 根目录 文件夹分门别类的放到根目录…...

网络地址转换(nat,easy ip,nat server)资源上传

实验概述 由内到外 nat&#xff0c;easy ip&#xff0c;转换的是源ip nat server 由外到内&#xff0c;转换的是目的IP 实验拓扑 结果验证 nat实验得到结果 1.ar1到ar3没有路由也可以访问 2.ar3配置telent后ar1也可以通过telnet远程配置 esay ip 如果ar2 g0/0/1接口ip非固…...

go的web开发框架gin(一)

一、简介 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。它具有类似 Martini 的 API&#xff0c;但性能比 Martini 快 40 倍。如果你需要极好的性能&#xff0c;使用 Gin 吧。 它的特性如下&#xff1a; 快速&#xff0c;基于 Radix 树的路由&#xff0c;小内存占用。没有…...

UVM寄存器模型——手写Ralf问题debug

寄存器模型是UVM中至关重要的一部分&#xff0c;如果没有寄存器模型&#xff0c;那么验证平台对于DUT内寄存器的访问方式将十分有限&#xff0c;对DUT运行状态的把控也会变得更为复杂。 在验证过程中&#xff0c;scoreboard或者其他验证组件经常需要了解当前时间某个寄存器的值…...

错误: 找不到或无法加载主类问题(已解决)

今天在虚拟机中安装了idea2023.2的版本&#xff0c;运行代码时发现错误找不到主类&#xff01; 直接说结论&#xff1a; 我先clean了一下target&#xff0c;然后重新build&#xff0c;发现maven报错了&#xff0c;idea2023.2默认使用了内置的maven&#xff0c;然后我切换了一下…...

【Python】os.scandir()函数示例以及和os.listdir()函数的对比优势

在 Python 中&#xff0c;os.scandir() 函数是一个用来列出指定目录下的条目&#xff08;包括文件和子目录&#xff09;的高效方式。它返回一个迭代器&#xff0c;不仅可以迭代目录中的所有条目&#xff0c;还能访问每个条目的文件属性&#xff0c;如文件类型、文件大小等&…...

暴利 选品大课:选品决定成败,教你多种大爆款选品方法(12节课)

课程目录 001.第一讲:选品决定成败.mp4 002.第二讲:选品也有生辰八字,mp4 003.第三讲:高热度选品底层逻辑,mp4 004,第四讲:高动销选品底层逻辑,mp4 005,第五讲:高点击选品底层逻辑,mp4 006.第六讲:高转化选品底层逻辑.mp4 007.第七讲:低付费选品底层逻辑.mp4 008,第八讲…...

Docker部署nacos集群

前提&#xff1a; 购买一台服务器 虚拟机也行 &#xff0c;无论是哪一个内存都要足够 阿里&#xff1a;https://ecs-buy.aliyun.com/ecs?spm5176.8789780.J_4267641240.2.1e7e39fbopfoRn#/custom/prepay/cn-hangzhou 腾讯 、华为。。。。我目前只使用过这三个。 下载 Xshell …...

centos7.9安装es7.12.0

下载es 国内镜像&#xff1a;https://mirrors.huaweicloud.com/elasticsearch/7.12.0/ 下载并上传内容到/usr/local目录下 解压&#xff1a; tar -zxvf /uar/local/elasticsearch-7.12.0-linux-x86_64.tar.gz安装 es一般不能用root启动&#xff0c;因此需要创建es:es用户和…...

【Linux网络编程】传输层中的TCP和UDP(UDP篇)

【Linux网络编程】传输层中的TCP和UDP&#xff08;UDP篇&#xff09; 目录 【Linux网络编程】传输层中的TCP和UDP&#xff08;UDP篇&#xff09;传输层再谈端口端口号范围划分认识知名端口号netstatiostatpidofxargs UDP协议UDP协议端格式UDP的特点面向数据报UDP的缓冲数据UDP使…...

第二十四天 | 501.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

题目&#xff1a;501.二叉搜索树中的插入操作 自己有一定的思路&#xff0c;但是遇到的难点&#xff1a; 可以找到val应该插入的位置&#xff0c;但如何建立新节点的结构呢&#xff1f;也就是说新建立的node应该怎么指&#xff0c;是搭建左孩子还是右孩子&#xff1f;又是应该…...

webpack查看各个阶段耗时示例:

一&#xff1a; 简单查看编译耗时 webpack5默认是开启profile的&#xff0c; webpack.config.js module.exports {entry: ./src/index.js,output: {filename: main.js}, }npm i core-jsimport core-js/stable src/index.js const util () > {return util }let zhang util…...

USB-OTG:1、OTG原理介绍

目录 &#x1f345;点击这里查看所有博文 随着自己工作的进行&#xff0c;接触到的技术栈也越来越多。给我一个很直观的感受就是&#xff0c;某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了&#xff0c;只有经常会用到的东西才有可能真正记…...