JavaSE List

news2024/11/18 9:29:15

目录

  • 1 预备知识-泛型(Generic)
    • 1.1 泛型的引入
    • 1.2 泛型类的定义的简单演示
  • 1.3 泛型背后作用时期和背后的简单原理
    • 1.4 泛型类的使用
    • 1.5 泛型总结
  • 2 预备知识-包装类(Wrapper Class)
    • 2.1 基本数据类型和包装类直接的对应关系
    • 2.2 包装类的使用,装箱(boxing)和拆箱(unboxing)
  • 3 List的使用
    • 3.1 常见方法
    • 3.2 练习题

1 预备知识-泛型(Generic)

1.1 泛型的引入

问题: 我们之前实现过的顺序表,只能保存 int 类型的元素,如果现在需要保存 指向 Person 类型对象的引用的顺序表,请问应该如何解决?如果又需要保存指向 Book 对象类型的引用呢?
回答:
首先,在学习多态过程中已知一个前提,基类的引用可以指向子类的对象。
其次,也已知 Object 是 java 中所有类的祖先类。
那么,要解决上述问题,我们很自然的想到一个解决办法,将我们的顺序表的元素类型定义成 Object 类型,这样我们的 Object 类型的引用可以指向 Person 类型的对象或者指向 Book 类型的对象了。这样,我们也就可以很自由的存储指向任意类型对象的引用到我们的顺序表了。
现在的 MyArrayList 虽然可以做到添加任意类型的引用到其中了,但会产生向下转型不安全,需要强制转换才能解决这个问题。
具体代码示例如下所示:

package Generic;
import org.omg.CORBA.Object;
/*
* 泛型是一个在java当中 比较难的语法
* */

/*
* 题目:写一个通用的顺序表?
*     Object是所有类的父类,哪怕这个类没有继承Object
* */


//通用的顺序表(不用泛型)
class MyArrayList{
    //public int elem;此时只能放int类型的元素
    public Object[] elem;//此时就能放所有类型的元素了
    public int usedSize;
    public MyArrayList(){
        this.elem = new Object[10];
    }

    public void add(Object data){
        this.elem[this.usedSize] = data;
        this.usedSize++;
    }

    public Object get(int pos){
        return this.elem[pos];
    }
}

public class TestDemo {
    public static void main(String[] args) {
        /*Object[] elem = new Object[10];
        elem[0] = 10;
        elem[1] = "fsasa";*/
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(19.8);
        myArrayList.add("fsfsa");

        //String str = myArrayList.get(2);此时会报错,这里发生了向下转型,向下转型本来就是不安全的。所以此时要进行强制类型转换才不会报错
        String str = (String) myArrayList.get(2);
        System.out.println(str);
    }
}

注意: 问题暴露的越早,影响越小。编译期间的问题只会让开发者感觉到,运行期间的错误会让所有的软件使用者承受错误风险。所以我们需要一种机制,可以 (1)增加编译期间的类型检查;(2)取消类型转换的使用。泛型就此诞生!

1.2 泛型类的定义的简单演示

泛型类的定义:

// 1. 尖括号 <> 是泛型的标志
// 2. E 是类型变量(Type Variable),变量名一般要大写
// 3. E 在定义时是形参,代表的意思是 MyArrayList 最终传入的类型,但现在还不知道
public class MyArrayList<E>{
    private E[] array;
    private int size;
    ...
}

注意: 泛型类可以一次有多个类型变量,用逗号分割。

1.3 泛型背后作用时期和背后的简单原理

  1. 泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念。
  2. 泛型代码在运行期间,就是我们上面提到的,利用 Object 达到的效果(这里不是很准确,以后会做说明)。

1.4 泛型类的使用

具体代码示例如下所示:

package Generic;
import org.omg.CORBA.Object;
/*
* 泛型是一个在java当中 比较难的语法
* 了解泛型就ok了 保存这份代码
* 以后可以当作字典进行查询
* */

/*
* 泛型:只存在于编译时期 只是编译时期
*    意义:
*    1、自动进行类型的检查
*    2、自动进行类型转换
* 泛型 在编译的时候,并不会进行指定类型的替换,而是拿着指定的类型进行检查
*     也就是说在编译的时候,拿着你指定的类型进行检查,记住并没有说是替换
*
* 编译的时候会进行类型擦除,编译的时候 编译都会把泛型擦除为Object,不是替换为Object
*
* 题目:写一个通用的顺序表?
*     Object是所有类的父类,哪怕这个类没有继承Object
*
* 1、class MyArrayList<T>{   <T>:代表占位符,表示当前这个类是一个泛型类
* 2、简单类型不能做泛型类型的参数:
*         MyArrayList<int> myArrayList1 = new MyArrayList<String>();
* 3、不能new 泛型类型的数组  this.elem = new T[10];
* 4、泛型类型的参数 不参与类型的组成 --》 泛型就是在编译时期的一种机制
* */


/*//通用的顺序表(不用泛型)
class MyArrayList{
    //public int elem;此时只能放int类型的元素
    public Object[] elem;//此时就能放所有类型的元素了
    public int usedSize;
    public MyArrayList(){
        this.elem = new Object[10];
    }

    public void add(Object data){
        this.elem[this.usedSize] = data;
        this.usedSize++;
    }

    public Object get(int pos){
        return this.elem[pos];
    }
}*/
//通用的顺序表(用泛型)
class MyArrayList<T>{
    //public int elem;此时只能放int类型的元素
    public T[] elem;//此时就能放所有类型的元素了
    public int usedSize;
    public MyArrayList(){
        // this.elem = new T[10];会报错,正确书写方式如下所示:
        this.elem = (T[])new Object[10];
    }

    public void add(T data){
        this.elem[this.usedSize] = data;
        this.usedSize++;
    }

    public T get(int pos){
        return this.elem[pos];
    }
}

class Anima{

}
class Cat extends Anima{

}
class Bird extends Anima{
    public void fly(){

    }
}
class Person{

}
public class TestDemo {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person);//类型@地址
        MyArrayList<String> myArrayList1 = new MyArrayList<>();
        System.out.println(myArrayList1);
        MyArrayList<Integer> myArrayList2 = new MyArrayList<Integer>();
        System.out.println(myArrayList2);
        MyArrayList<Double> myArrayList3 = new MyArrayList<Double>();
        System.out.println(myArrayList3);
    }
    public static void main4(String[] args) {
        MyArrayList<String> myArrayList1 = new MyArrayList<>();//后面尖括号里的东西可写可不写,一般情况下都不写
        myArrayList1.add("fsfsa");
        myArrayList1.add("feihan");
        myArrayList1.add("bit");
        String str = myArrayList1.get(2);//泛型自动进行了强制类型转换
        System.out.println(str);
    }
    public static void main3(String[] args) {
        Anima anima = new Cat();
        Bird bird = (Bird)anima;
        bird.fly();//此时是飞不起来的
        //这里牵扯到一个编译时多态和运行时多态
        //就是在编译的时候是anima这个对象,但是在运行时就是cat这个对象,所以说第一条语句执行完毕以后这个anima就是一个cat对象

        //现在要把cat这个对象转成bird对象肯定不行的,因为:
        //类型转换只能是父类子类之间相互转换,同类的不同派生的对象之间是不能相互转换的
        //所以它此时强转失败了,自然也不能飞起来了
    }

    public static void main2(String[] args) {
        //MyArrayList<int> myArrayList1 = new MyArrayList<String>();
    }
    public static void main1(String[] args) {
       /* *//*Object[] elem = new Object[10];
        elem[0] = 10;
        elem[1] = "fsasa";*//*
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(19.8);
        myArrayList.add("fsfsa");

        //String str = myArrayList.get(2);此时会报错,这里发生了向下转型,向下转型本来就是不安全的。所以此时要进行强制类型转换才不会报错
        String str = (String) myArrayList.get(2);
        System.out.println(str);*/

        MyArrayList<String> myArrayList1 = new MyArrayList<String>();//后面尖括号里的东西可写可不写,一般情况下都不写
        //myArrayList1.add(1);
        //myArrayList1.add(19.8);
        myArrayList1.add("fsfsa");
        myArrayList1.add("feihan");
        myArrayList1.add("bit");

        String str = myArrayList1.get(2);//泛型自动进行了强制类型转换
        System.out.println(str);

        MyArrayList<Integer> myArrayList2 = new MyArrayList<Integer>();
        myArrayList2.add(1);
        myArrayList2.add(2);

        int val = myArrayList2.get(1);
        System.out.println(val);

        MyArrayList<Double> myArrayList3 = new MyArrayList<Double>();
        myArrayList3.add(19.8);
    }
}

通过以上代码,我们可以看到泛型类的一个使用方式:只需要在所有类型后边跟尖括号,并且尖括号内是真正的类型,即 T 可以看作的最后的类型。
注意: myArrayList 只能想象成 T 的类型,但实际上 T 的类型还是 Object。

1.5 泛型总结

  1. 泛型是为了解决某些容器、算法等代码的通用性而引入,并且能在编译期间做类型检查。
  2. 泛型利用的是 Object 是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。
  3. 泛型是一种编译期间的机制,即MyArrayList <Person>MyArrayList<Book> 在运行期间是一个类型。
  4. 泛型是 java 中的一种合法语法,标志就是尖括号 <>。

2 预备知识-包装类(Wrapper Class)

Object 引用可以指向任意类型的对象,但有例外出现了,8 种基本数据类型不是对象,那岂不是刚才的泛型机制要失效了?
实际上也确实如此,为了解决这个问题,java 引入了一类特殊的类,即这 8 种基本数据类型的包装类,在使用过程中,会将类似 int 这样的值包装到一个对象中去。

2.1 基本数据类型和包装类直接的对应关系

基本数据类型和包装类直接的对应关系如下图所示:
在这里插入图片描述
基本就是类型的首字母大写,除了 Integer 和 Character。

2.2 包装类的使用,装箱(boxing)和拆箱(unboxing)

装包/装箱: 把简单类型 包装成 对应的包装类。
拆包/拆箱: 把包装类 变为 简单类型。
我们通过代码对装箱和拆箱进行理解,具体代码示例如下所示:

package Generic;
public class TestDemo {
    /*
    * 装包/装箱:把简单类型 包装成 对应的包装类
    *    自动装包:
    *    显示装包:
    * 拆包/拆箱:把包装类 变为 简单类型
    *    自动拆箱:
    *    显示拆箱:
    * */
    public static void main(String[] args) {
        /*
        * 选择题
        * */
        Integer a = 139;
        Integer b = 139;
        System.out.println(a == b);//范围的问题导致这个结果是true,还是false不一定
    }
    public static void main1(String[] args) {
        Integer i = 10;
        int a = i;//自动拆箱   底层其实也是调用了i.intValue()
        System.out.println(a);
        int a2 = i.intValue();//显示拆箱
        System.out.println(a2);
        double d = i.doubleValue();
        System.out.println(d);
    }
    public static void main2(String[] args) {
        int a = 10;
        Integer integer1 = new Integer(a);//显示的装包
        System.out.println(integer1);
        Integer integer2 = Integer.valueOf(a);//显示装包
        System.out.println(integer2);

        Integer integer3 = a;//自动装包  其实也是调用了Integer.valueOf
    }
   }

注意: 自动装箱和自动拆箱是工作在编译期间的一种机制。

3 List的使用

List是位于java.util下的一个接口,有序集合(也称为序列)。

3.1 常见方法

List(线性表):

方法解释
boolean add(E e)尾插 e
void add(int index, E element)将 e 插入到 index 位置
boolean addAll(Collection<? extends E> c)尾插 c 中的元素
E remove(int index)删除 index 位置元素
boolean remove(Object o)删除遇到的第一个 o
E get(int index)获取下标 index 位置元素
E set(int index, E element)将下标 index 位置元素设置为 element
void clear()清空
boolean contains(Object o)判断 o 是否在线性表中
int indexOf(Object o)返回第一个 o 所在下标
int lastIndexOf(Object o)返回最后一个 o 的下标
List subList(int fromIndex, int toIndex)截取部分 list

ArrayList(顺序表):

方法解释
ArrayList()无参构造
ArrayList(Collection<? extends E> c)利用其他 Collection 构建 ArrayList
ArrayList(int initialCapacity)指定顺序表初始容量

LinkedList(链表):

方法解释
LinkedList()无参构造

代码示例如下所示:

package Generic;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class TestDemo2 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        System.out.println(list);

       /* List<Integer> list1 = new ArrayList<>();
        list1 = list.subList(1,3);
        System.out.println(list1);

        list1.set(0,88);
        System.out.println(list1);
        System.out.println(list);*/

        //迭代器 用来打印集合中的元素的
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //建议大家慎用iterator.remove()
        iterator.remove();
        System.out.println(list);
    }
    public static void main1(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        /*
        * ArrayList底层是一个数组,每次放元素的时候都是放在了数组的最后。
        * public boolean add(E e){}  add的是一个boolean类型
        * public void add(int index,E element){}  这个方法是放在index位置
        * 问题:ArrayList底层是数组,那么他有多大?
        * 1.new ArrayList<>() 调用的是不带有参数的构造方法
        *   那么大小默认为0。
        * 2.当调用默认的构造方法之后,当你添加第一个元素的时候会进行扩容,第一系扩容的时候,大小为10;
        * 3.当后续进行扩容的时候,是进行了1.5倍的方式进行扩容
        * */
        list.add(1);
        System.out.println(list);

        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(10);
        arrayList.add(20);
        list.addAll(arrayList);
        System.out.println(list);
        list.remove(1);
        /*
         * remove这块要注意如果要remove的不是1下标对应的数字,而要remove数组中第一个见到的1,则应该这样做:
         *  Integer integer = 1;
         *  list.remove(integer);
         * */
        System.out.println(list);
    }
}

3.2 练习题

题目1: 学校有若干学生(学生对象放在一个List中),每个学生有一个姓名(String)、班级(String)和考试成绩属性(double)。每次考试结束后,每个学生都获得了一个考试成绩。遍历list集合,并把学生对象的属性打印出来。
解题代码如下所示:

package Generic;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class Student{
    public String name;
    public int age;
    public double score;

    //构造方法和toString方法的快捷键是alt+insert
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student("feihan",19,89.9));
        list.add(new Student("feihan1",29,99.9));

        //下面为四种不同的打印方式:
       /* for(int i = 0;i < list.size();i++){
            System.out.println(list.get(i));
        }*/

        /*for(Student student : list){
            System.out.println(student);
        }*/

        /*Iterator<Student> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }*/

        System.out.println(list);
    }
    }

题目2: 有一个List当中存放的是整型的数据,要求使用Collections.sort对List进行排序。
解题代码如下所示:

package Generic;

import java.util.*;
public class TestDemo2 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(9);
        Collections.sort(list);
        System.out.println(list);
    }}

题目三: 删除第一个字符串当中出现的第二个字符串中的字符。例如:

String str1 = “welcome to feihan”;
String str2 =“come”;
输出结果:wl t fihan

解题思路:

str1 = “welcome to feihan”
str2 =“come”;
拿着str1的每个字符,判断str2当中是否包含这个字符,如果不包含,那么就把这个字符放到ArrayList当中。

利用 ArrayList 解题代码如下所示:

package Generic;

import java.util.*;

public class TestDemo2 {
    public static List<Character> func(String str1,String str2){
        List<Character> ret = new ArrayList<>();
        for(int i =0;i < str1.length();i++){
            char ch = str1.charAt(i);//w
            if(!str2.contains(ch+"")){
                ret.add(ch);
            }
        }
        return ret;
    }
    public static void main(String[] args) {
        List<Character>  list = func("welcome to feihan","come");
        System.out.println(list);
        //换种打印方式
        for(int i = 0; i < list.size();i++){
            System.out.print(list.get(i));       
             }
    }}

利用 StringBuilder 解题代码如下所示:

package Generic;

import java.util.*;

public class TestDemo2 {
    public static String func(String str1,String str2){
        StringBuilder sb = new StringBuilder();
        for(int i =0;i < str1.length();i++){
            char ch = str1.charAt(i);//w
            if(!str2.contains(ch+"")){
                sb.append(ch);
            }
        }
        return sb.toString();
    }
     public static void main(String[] args) {
        String ret = func("welcome to feihan","come");
        System.out.println(ret);
    }}

题目四: 模拟扑克牌买牌、洗牌和发牌的过程。
解题代码如下所示:

package Generic;

import java.util.*;

class Card{
    public String suit;
    public int rank;

    public Card(String suit, int rank) {
        this.suit = suit;
        this.rank = rank;
    }

    @Override
    public String toString() {
       /* return "Card{" +
                "suit='" + suit + '\'' +
                ", rank=" + rank +
                '}';*/
        return "["+suit+","+rank+"]";
    }
}
class DeckCard{
    public static final String[] suits ={"♥","♠","♦","♣"};
    public List<Card> buyCard(){
        List<Card> cardList = new ArrayList<>();
        for(int i = 0; i < 4;i++){
            for (int j = 0; j <=13 ; j++) {
                String suit = suits[i];
                int rank = j;
                Card card = new Card(suit,rank);
                cardList.add(card);
            }
        }
        return cardList;
    }
    public void swap(List<Card> cardList,int i,int j){
        Card tmp = cardList.get(i);
        cardList.set(i,cardList.get(j));
        cardList.set(j,tmp);
    }

    public void washCard(List<Card> cardList){
        for (int i = cardList.size()-1; i > 0 ; i--) {
            Random random = new Random();
            int rand = random.nextInt(i);
            swap(cardList,i,rand);
        }
    }
}

public class TestDemo2 {
    public static void main(String[] args) {
        DeckCard deckCard = new DeckCard();
        List<Card> cardList = deckCard.buyCard();
        System.out.println("=========买牌============");
        System.out.println(cardList);
        System.out.println("=========洗牌============");
        deckCard.washCard(cardList);
        System.out.println(cardList);
        System.out.println("=========发牌============");
        //3个人 每个人5张牌 轮流
        List<Card> hands1 = new ArrayList<>();
        List<Card> hands2 = new ArrayList<>();
        List<Card> hands3 = new ArrayList<>();

        List<List<Card>> hands = new ArrayList<>();
        hands.add(hands1);
        hands.add(hands2);
        hands.add(hands3);

     /*   一把揭
         for (int i = 0; i < 3 ; i++) {
            for (int j = 0; j < 5; j++) {
                //揭牌
                Card card = cardList.remove(0);
                hands.get(i).add(card);
            }
        }*/
        //轮流揭牌
        for (int i = 0; i < 5 ; i++) {
            for (int j = 0; j < 3; j++) {
                //揭牌
                Card card = cardList.remove(0);
                hands.get(j).add(card);
            }
        }
        System.out.println("第一个人:");
        System.out.println(hands1);
        System.out.println("第二个人:");
        System.out.println(hands2);
        System.out.println("第三个人:");
        System.out.println(hands3);

        System.out.println("剩余的牌:");
        System.out.println(cardList);
    }}

题目五: 杨辉三角
题目链接:https://leetcode.cn/problems/pascals-triangle/
解题思路如下图所示:在这里插入图片描述
解题代码如下所示:

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ret = new ArrayList<>();
        if(numRows <= 0) return ret;
        //第一行的list
        List<Integer> list = new ArrayList<>();
        list.add(1);
        //把第一行的list放到ret当中
        ret.add(list)

        for(int i = 1; i < numRows; i++){
            List<Integer> curRow = new ArrayList<>();
            curRow.add(1);
            for(int j = 1; j < i ; j++){
                //确定的是当前行的每个元素 == 上一行的当前列+上一行的前一列就是我当前需要添加的数字
                List<Integer> preRow = ret.get(i-1);
                int num = preRow.get(j-1)+preRow.get(j);
                curRow.add(num);      
            }
            //手动在当前行的最后一个位置添加一个1
            curRow.add(1);
            ret.add(curRow);
        }
        return ret;
    }
}

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

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

相关文章

【C++面向对象侯捷下】2.转换函数 | 3.non-explicit-one-argument ctor

文章目录 operator double() const {} 歧义了 标准库的转换函数

美创科技参编《数字政府建设与发展研究报告(2023)》 正式发布

9月14日&#xff0c;中国信息通信研究院云计算与大数据研究所牵头编制的《数字政府建设与发展研究报告&#xff08;2023&#xff09;》正式发布。 美创科技结合在政务数据安全领域的丰富实践经验&#xff0c;参与报告编写。 《数字政府建设与发展研究报告》 以“技术、业务、数…

2023工博会强势回归!智微工业携八大系列重磅亮相

中国国际工业博览会&#xff08;简称"中国工博会"&#xff09;自1999年创办以来&#xff0c;历经二十余年发展创新&#xff0c;通过专业化、市场化、国际化、品牌化运作&#xff0c;已发展成为通过国际展览业协会&#xff08;UFI&#xff09;认证、中国工业领域规模最…

flex布局与float布局

float布局 俩栏 三栏 flex布局

Leetcode199. 二叉树的右视图

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 题解&#xff1a;力扣&#xff08;LeetCode&#xff09…

大型集团借力泛微搭建语言汇率时区统一、业务协同的国际化OA系统

国际化、全球化集团&#xff0c;业务遍布全世界&#xff0c;下属公司众多&#xff0c;集团对管理方式和企业文化塑造有着很高的要求。不少大型集团以数字化方式助力全球统一办公&#xff0c;深化企业统一管理。 面对大型集团全球化的管理诉求&#xff0c;数字化办公系统作为集…

虚拟机部署linux网络连接配置

1、虚拟机安装linux后&#xff0c;配置网络访问 虚拟机网络设置为NAT模式 linux网络配置好IP&#xff0c;主要是以下网络配置 2、linux没有ifconfig命令&#xff0c;ifconfig命令是在net-tools.x86_64包里 yum install net-tools.x86_64安装

207.Flink(二):架构及核心概念,flink从各种数据源读取数据,各种算子转化数据,将数据推送到各数据源

一、Flink架构及核心概念 1.系统架构 JobMaster是JobManager中最核心的组件,负责处理单独的作业(Job)。一个job对应一个jobManager 2.并行度 (1)并行度(Parallelism)概念 一个特定算子的子任务(subtask)的个数被称之为其并行度(parallelism)。这样,包含并行子任…

八大排序(四)--------直接插入排序

本专栏内容为&#xff1a;八大排序汇总 通过本专栏的深入学习&#xff0c;你可以了解并掌握八大排序以及相关的排序算法。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;八大排序汇总 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库…

蓝桥杯每日一题2023.9.22

4960. 子串简写 - AcWing题库 题目描述 题目分析 原本为纯暴力但是发现会超时&#xff0c;可以加入前缀和&#xff0c;从前往后先记录一下每个位置c1出现的次数 再从前往后扫一遍&#xff0c;如果遇到c2就将答案加上此位置前的所有c1的个数&#xff08;直接加上此位置的前缀…

Mybatis学习笔记4 用javassist动态实现DAO接口基于接口的CRUD

Mybatis学习笔记3 在Web中应用Mybatis_biubiubiu0706的博客-CSDN博客 上篇最后在DAO实现类中,代码固定,没有业务逻辑,这篇笔记中对该实现类进行封装,就是说,以后不用写DAO实现类了 我们不难发现&#xff0c;这个dao实现类中的⽅法代码很固定&#xff0c;基本上就是⼀⾏代码&am…

【面试经典150 | 双指针】三数之和

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;暴力枚举方法二&#xff1a;双指针 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对…

AIGC|从革新内容创作到社会共识建立,迎接全新技术维度

在人工智能的巨浪之下&#xff0c;我们身临一场前所未有的文化演变&#xff0c;一股革命性的力量正在重新定义我们的创造性边界。这股力量不是人类的智慧&#xff0c;而是人工智能生成内容&#xff08;AIGC&#xff09;技术&#xff0c;它正以前所未有的速度和广度改变着我们的…

上PICO,沉浸式观看亚运直播,参与跨国界游戏竞技

备受瞩目的杭州第19届亚运会&#xff0c;将于9月23日正式开幕。据悉&#xff0c;这也是有史以来项目最多的一届亚运会&#xff0c;除部分传统奥运项目外&#xff0c;还包含武术、藤球、板球、克柔术、柔术等亚洲特色项目&#xff0c;以及霹雳舞、电子竞技等深受年轻人喜爱的新兴…

数字赋能 融链发展 ——2023工博会数字化赋能专精特新“小巨人”企业高质量发展论坛顺利举行

编者按&#xff1a;2023年政府工作报告提出“加快传统产业和中小企业数字化转型”要求&#xff0c;按照《“十四五”促进中小企业发展规划》《关于开展中小企业数字化转型城市试点工作的通知》等文件的部署&#xff0c;通过开展城市试点&#xff0c;支持地方政府综合施策&#…

AI视频剪辑:批量智剪技巧大揭秘

对于许多内容创作者来说&#xff0c;视频剪辑是一项必不可少的技能。然而&#xff0c;传统的视频剪辑方法需要耗费大量的时间和精力。如今&#xff0c;有一种全新的剪辑方式正在改变这一现状&#xff0c;那就是批量AI智剪。这种智能化的剪辑方式能够让你在短时间内轻松剪辑大量…

pg数据表同步到hive表数据压缩总结

1、背景 pg库存放了大量的历史数据&#xff0c;pg的存储方式比较耗磁盘空间&#xff0c;pg的备份方式&#xff0c;通过pgdump导出后&#xff0c;进行gzip压缩&#xff0c;压缩比大概1/10&#xff0c;随着数据的积累磁盘空间告警。为了解决pg的压力&#xff0c;尝试采用hive数据…

如何在没有第三方.NET库源码的情况,调试第三库代码?

大家好&#xff0c;我是沙漠尽头的狼。 本方首发于Dotnet9&#xff0c;介绍使用dnSpy调试第三方.NET库源码&#xff0c;行文目录&#xff1a; 安装dnSpy编写示例程序调试示例程序调试.NET库原生方法总结 1. 安装dnSpy dnSpy是一款功能强大的.NET程序反编译工具&#xff0c;…

Qt创建线程(使用moveToThread方法创建子线程)

1.moveTothread方法: &#xff08;1&#xff09;要使用moveToThread方法必须继承与QObject类 &#xff08;2&#xff09;创建任务对象时不能指定父对象 例子&#xff1a; MyWork* work new MyWork(this); // error MyWork* work new MyWork; // ok &#xff08;3&#…

常用的深度学习自动标注软件

0. 简介 自动标注软件是一个非常节省人力资源的操作&#xff0c;而随着深度学习的发展&#xff0c;这些自动化标定软件也越来越多。本文章将会着重介绍其中比较经典的自动标注软件 1. AutoLabelImg AutoLabelImg 除了labelimg的初始功能外&#xff0c;额外包含十多种辅助标注…