Java —— String类

news2024/9/29 5:27:59

目录

1. String类的重要性

2. 常用方法

2.1 字符串构造

2.2 String对象的比较

2.3 字符串查找

2.4 转化

1. 数值和字符串转化

2. 大小写转换

3. 字符串转数组

4. 格式化

2.5 字符串替换

2.6 字符串拆分

2.7 字符串截取

2.8 其他操作方法

2.9 字符串常量池

2.9.1 创建对象的思考

2.9.2 字符串常量池(StringTable)

2.9.3 再谈String对象创建

2.10 字符串的不可变性

2.11 字符串修改

3. StringBuilder和StringBuffer

3.1 StringBuilder的介绍

3.2 面试题


1. String类的重要性

在C语言中已经涉及到字符串了,但是在C语言中要表示字符串只能使用字符数组或者字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想,而字符串应用又非常广泛,因此Java语言专门提供了String类。

2. 常用方法

2.1 字符串构造

String类提供的构造方式非常多,常用的就以下三种:

public class Test {
    public static void main(String[] args) {
        // 双引号引起来的若干字符就是字符串, 即 "hello", 我们称为字符串常量.
        String str1 = "hello";
        // 把 "hello" 赋值给 引用变量 str1, str1 实际上存的是 "hello" 这个对象 的地址
        System.out.println(str1);

        // 调用String构造方法传入一个字符串来构造一个字符串对象, 与上文写法相同
        String str2 = new String("abc");
        System.out.println(str2);

        // 把字符数组转变为字符串, 就能得到字符串对象
        char[] chars = {'c','x','k'};
        String str3 = new String(chars);
        System.out.println(str3);
    }
}

其他方法需要用到时,大家参考Java在线文档:String官方文档

【注意】

1. String是引用类型,内部并不存储字符串本身,在String类的实现源码中,String类实例变量如下:

public class Test {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("world");
        String s3 = s1;
        
        System.out.println(s3);
        System.out.println(s1.length());
    }
}

2. 在Java中""引起来的也是String类型对象。

// 打印"hello"字符串(String对象)的长度
System.out.println("hello".length());

2.2 String对象的比较

字符串的比较是常见操作之一,比如:字符串排序。Java中总共提供了4中方式:

1. ==比较是否引用同一个对象

注意:对于内置类型,==比较的是变量中的值;对于引用类型==比较的是引用中的地址。

2. A.equals(B)比较内容是否相同

public class Test {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");

        System.out.println(s1 == s2);   // false
        System.out.println(s1.equals(s2));  // true
        System.out.println(s1.equalsIgnoreCase(s2));    // 忽略大小写 是否相同 true

        int a = 10;
        int b = 20;
        System.out.println(a == b); // 基本类型 false
    }
}

3. int compareTo(String s) 方法: 按照字典序进行比较

与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:

1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值

2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值

public class Test {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("Hello");

        int ret = s1.compareTo(s2); // s1和s2比较
        //int ret = s1.compareToIgnoreCase(s2);   // s1和s2 忽略大小写进行比较

        if (ret > 0) {
            System.out.println("s1>s2");
        } else if (ret == 0) {
            System.out.println("s1==s2");
        } else {
            System.out.println("s1<s2");
        }
    }
}

h的ASCII码值大于H的ASCII码值.

4. int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较

public static void main(String[] args) {
    String s1 = new String("abc");
    String s2 = new String("ac");
    String s3 = new String("ABc");
    String s4 = new String("abcdef");
    System.out.println(s1.compareToIgnoreCase(s2)); // 不同输出字符差值-1
    System.out.println(s1.compareToIgnoreCase(s3)); // 相同输出 0
    System.out.println(s1.compareToIgnoreCase(s4)); // 前k个字符完全相同,输出长度差值 -3
}

2.3 字符串查找

字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:

方法

功能

char charAt(int index)

返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常

int indexOf(int ch)

返回ch第一次出现的位置,没有返回-1

int indexOf(int ch, int fromIndex)

从fromIndex位置开始找ch第一次出现的位置,没有返回-1

int indexOf(String str)

返回str第一次出现的位置,没有返回-1

int indexOf(String str, int fromIndex)

从fromIndex位置开始找str第一次出现的位置,没有返回-1

int lastIndexOf(int ch)

从后往前找,返回ch第一次出现的位置,没有返回-1

int lastIndexOf(int ch, int fromIndex)

从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1

int lastIndexOf(String str)

从后往前找,返回str第一次出现的位置,没有返回-1

int lastIndexOf(String str, int fromIndex)

从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1

public static void main(String[] args) {
    String s = "aaabbbcccaaabbbccc";
    System.out.println(s.charAt(3)); // 'b'
    System.out.println(s.indexOf('c')); // 6
    System.out.println(s.indexOf('c', 10)); // 15
    System.out.println(s.indexOf("bbb")); // 3
    System.out.println(s.indexOf("bbb", 10)); // 12
    System.out.println(s.lastIndexOf('c')); // 17
    System.out.println(s.lastIndexOf('c', 10)); // 8
    System.out.println(s.lastIndexOf("bbb")); // 12
    System.out.println(s.lastIndexOf("bbb", 10)); // 3
}

注意:上述方法都是实例方法。

2.4 转化

1. 数值和字符串转化

class Student {
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public static void main(String[] args) {
    // 数字转字符串
    String s1 = String.valueOf(1234);
    String s2 = String.valueOf(12.34);
    String s3 = String.valueOf(true);
    String s4 = String.valueOf(new Student("Hanmeimei", 18));
    System.out.println(s1);
    System.out.println(s2);
    System.out.println(s3);
    System.out.println(s4);
    System.out.println("=================================");

    // 字符串转数字
    // 注意:Integer、Double等是Java中的包装类型
    int data1 = Integer.parseInt("1234");
    double data2 = Double.parseDouble("12.34");
    System.out.println(data1);
    System.out.println(data2);
}

2. 大小写转换

public static void main(String[] args) {
    String s1 = "hello";
    String s2 = "HELLO";
    // 小写转大写
    System.out.println(s1.toUpperCase());
    // 大写转小写
    System.out.println(s2.toLowerCase());
}

3. 字符串转数组

public static void main(String[] args) {
    String s = "hello";
    // 字符串转数组
    char[] ch = s.toCharArray();
    for (int i = 0; i < ch.length; i++) {
        System.out.print(ch[i]);
    }
    System.out.println();
    // 数组转字符串
    String s2 = new String(ch);
    System.out.println(s2);
}

4. 格式化

public static void main(String[] args) {
    String s = String.format("%d-%d-%d", 2023,11,21);
    System.out.println(s);
}

2.5 字符串替换

使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:

方法

功能

String replaceAll(String regex, String replacement)

替换所有的指定内容

String replaceFirst(String regex, String replacement)

替换首个内容

public static void main(String[] args) {
    String str1 = "ababcabcdabcdef";
    /*String ret = str1.replace('a','p');
    System.out.println(ret);

    String ret2 = str1.replace("ab","pk");
    System.out.println(ret2);

    String ret = str1.replaceAll("abc","pkrg");
    System.out.println(ret);
*/
    String ret = str1.replaceFirst("abc", "pkrg");
    System.out.println(ret);
}

注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.

2.6 字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。

可用方法如下:

方法

功能

String[] split(String regex)

将字符串全部拆分

String[] split(String regex, int limit)

将字符串以指定的格式,拆分为limit组

String str = "zhangsan&wangwu&zhaoliu&lisi";
String[] ret = str.split("&");
System.out.println(Arrays.toString(ret));

String str = "zhangsan&wangwu&zhaoliu&lisi";
String[] ret = str.split("&", 2);
System.out.println(Arrays.toString(ret));

    public static void main(String[] args) {
        String str2 = "127.0.0.1";
        String[] ret2 = str2.split("\\.");
        for (String x : ret2) {
            System.out.println(x);
        }
        System.out.println("====================");

        String str3 = "127\\0\\0\\1";
        String[] ret3 = str3.split("\\\\");
        for (String x : ret3) {
            System.out.println(x);
        }
        System.out.println("====================");

        String[] ret4 = str3.split("/");
        for (String x : ret3) {
            System.out.println(x);
        }
        System.out.println("====================");

        String str4 = "name=zhangsan&age=18";
        String[] ret5 = str4.split("=|&");
        for (String x : ret5) {
            System.out.println(x);
        }
    }

注意事项:

  1. 字符"|","*","+"都得加上转义字符,前面加上"\\" .
  2. 而如果是"\" ,那么就得写成"\\\\" .
  3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.

多次拆分

    public static void main(String[] args) {
        String str = "name=zhangsan&age=18";
        String[] result = str.split("&");
        for (int i = 0; i < result.length; i++) {
            String[] temp = result[i].split("=");
            System.out.println(temp[0] + " = " + temp[1]);
        }
    }

这种代码在开发之中会经常出现.


2.7 字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:

方法

功能

String substring(int beginIndex)

从指定索引截取到结尾

String substring(int beginIndex, int endIndex)

截取部分内容

    public static void main(String[] args) {
        String str = "helloworld" ;
        System.out.println(str.substring(5));
        System.out.println(str.substring(0, 5));
        // 字符串当中的库函数 基本上只要改变 返回的都是一个全新的对象
    }

注意事项:

  1. 索引从0开始
  2. 注意前闭后开区间的写法, substring[0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

2.8 其他操作方法

方法

功能

String trim()

去掉字符串中的左右空格,保留中间空格

String toUpperCase()

字符串转大写

String toLowerCase()

字符串转小写

    public static void main(String[] args) {
        String str = " hello hello      ";
        System.out.println(str);
        String ret = str.trim();//去除掉左右两边的空格
        System.out.print(ret);
        System.out.println("pppppp");
    }

trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等).

2.9 字符串常量池

"池" 是编程中的一种常见的, 重要的提升效率的方式, 我们会在未来的学习中遇到各种 "内存池", "线程池", "数据库连接池" ....
比如:家里给大家打生活费的方式
1. 家里经济拮据,每月定时打生活费,有时可能会晚,最差情况下可能需要向家里张口要,速度慢
2. 家里有矿,一次性打一年的生活费放到银行卡中,自己随用随取,速度非常快
方式2,就是池化技术的一种示例,钱放在卡上,随用随取,效率非常高。常见的池化技术比如:数据库连接池、线程池等。

为了节省存储空间以及程序的运行效率,Java中引入了:

1. Class文件常量池:每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息

2. 运行时常量池:在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份

3. 字符串常量池

2.9.1 创建对象的思考

    public static void main(String[] args) {
        String str1 = "abcd";
        String str2 = "abcd";
        String str3 = new String("abcd");
        String str4 = new String("abcd");

        System.out.println(str1 == str2);
        System.out.println(str3 == str4);
        System.out.println(str1 == str3);
    }

上述程序创建方式类似,为什么s1和s2引用的是同一个对象,而s3和s4不是呢?

在Java程序中,类似于:1, 2, 3,3.14,“hello”等字面类型的常量经常频繁使用,为了使程序的运行速度更快、更节省内存,Java为8种基本数据类型和String类都提供了常量池。

字符串常量池底层是一个StringTable的哈希表.

字符串常量池是存放在堆当中的一块区域. 它有一个特点是: 只要是双引号""引起来的, 就会有两步操作.

首先, 在字符串常量池中检查是否有双引号引起来的对象(比如"abcd"), 如果没有就把它放进去.
然后在第二次再要放一个"abcd"的时候, 就会去检查在常量池当中, 是否有"abcd", 如果有就不会再重复存储一次了.
也就是说, 在字符串常量池中只会去维护一个"abcd"对象, 所以只要"abcd"存过, 就不会再存了.
这样有一个好处, 节省了内存, 提高了效率.
那么它是如何存进字符串常量池?

我们先来画一个草图简单理解.

注: 以上图中所有的"地址"都是随意写出来的, 以便演示, 不是真实情况下的地址.


接下来我们来看正确的图示.


2.9.2 字符串常量池(StringTable)

字符串常量池在JVM中是StringTable类,实际是一个固定大小的HashTable,不同JDK版本下字符串常量池的位置以及默认大小是不同的:

JDK版本

字符串常量池位置

大小设置

Java6

方法区

固定大小:1009

Java7

堆中

固定大小:1009

Java8

堆中

可设置,有范围限制,最小是1009

2.9.3 再谈String对象创建

1. 直接使用字符串常量进行赋值

public static void main(String[] args) {
    String s1 = "hello";
    String s2 = "hello";
    System.out.println(s1 == s2); // true
}

2. 通过new创建String类对象

结论:只要是new的对象,都是唯一的。

通过上面例子可以看出:使用常量串创建String类型对象的效率更高,而且更节省空间。用户也可以将创建的字符串对象通过intern 方式添加进字符串常量池中。

3. intern方法

intern 是一个native方法(Native方法指:底层使用C++实现的,看不到其实现的源代码),该方法的作用是手动将创建的String对象添加到常量池中。

public static void main(String[] args) {
    char[] ch = new char[]{'a', 'b', 'c'};
    String s1 = new String(ch); // s1对象并不在常量池中
    //s1.intern(); // s1.intern();调用之后,会将s1对象的引用放入到常量池中
    String s2 = "abc"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
    System.out.println(s1 == s2);
}

// 输出false
// 将上述intern方法打开之后,就会输出true

注意:在Java6 和 Java7、8中Intern的实现会有些许的差别。

面试题:请解释String类中两种对象实例化的区别
JDK1.8中
1. String str = "hello";
只会开辟一块堆内存空间,保存在字符串常量池中,然后str共享常量池中的String对象
2. String str = new String("hello");
会开辟两块堆内存空间,字符串"hello"保存在字符串常量池中,然后用常量池中的String对象给新开辟的String对象赋值。
3. String str = new String(new char[]{'h', 'e', 'l', 'l', 'o'});
现在堆上创建一个String对象,然后利用copyof将重新开辟数组空间,将参数字符串数组中内容拷贝到String对象中

2.10 字符串的不可变性

String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:

1. String类在设计时就是不可改变的,String类实现描述中已经说明了

以下来自JDK1.8中String类的部分实现:

String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:

  1. String类被final修饰,表明该类不能被继承
  2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。

2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象

比如replace 方法:

【纠正】网上有些人说:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。

这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改。

final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。

public static void main(String[] args) {
    final int array[] = {1,2,3,4,5};
    array[0] = 100;
    System.out.println(Arrays.toString(array));
    // array = new int[]{4,5,6}; // 编译报错:Error:(19, 9) java: 无法为最终变量array分配值
}
为什么 String 要设计成不可变的?(不可变对象的好处是什么?)
方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
不可变对象是线程安全的.
不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.

那如果想要修改字符串中内容,该如何操作呢?

2.11 字符串修改

注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下。

public static void main(String[] args) {
    String s = "hello";
    s += " world";
    System.out.println(s); // 输出:hello world
}

但是这种方式不推荐使用,因为其效率非常低,中间创建了好多临时对象。

public static void main(String[] args) {
    long start = System.currentTimeMillis();
    String s = "";
    for(int i = 0; i < 100000; ++i){
        s += i;
    }
    long end = System.currentTimeMillis();
    System.out.println(end - start);

    start = System.currentTimeMillis();
    StringBuffer sbf = new StringBuffer("");
    for(int i = 0; i < 100000; ++i){
        sbf.append(i);
    }
    end = System.currentTimeMillis();
    System.out.println(end - start);

    start = System.currentTimeMillis();
    StringBuilder sbd = new StringBuilder();
    for(int i = 0; i < 100000; ++i){
        sbd.append(i);
    }

    end = System.currentTimeMillis();
    System.out.println(end - start);
}

输出:
27199
3
2

可以看待在对String类进行修改时,效率是非常慢的,因此:尽量避免对String的直接需要,如果要修改建议尽量使用StringBuffer或者StringBuilder。

3. StringBuilder和StringBuffer

3.1 StringBuilder的介绍

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的,这里介绍 StringBuilder常用的一些方法.

这两个类也能表示字符串, 但是字符串可以直接赋值, 它们两个是不能直接赋值的.

方法

说明

StringBuffer append(String str)

在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、double、float、int、long、Object、String、StringBuff的变量

char charAt(int index)

获取index位置的字符

int length()

获取字符串的长度

int capacity()

获取底层保存字符串空间总的大小

void ensureCapacity(int mininmumCapacity)

扩容

void setCharAt(int index, char ch)

将index位置的字符设置为ch

int indexOf(String str)

返回str第一次出现的位置

int indexOf(String str, int fromIndex)

从fromIndex位置开始查找str第一次出现的位置

int lastIndexOf(String str)

返回最后一次出现str的位置

int lastIndexOf(String str, int fromIndex)

从fromIndex位置开始找str最后一次出现的位置

StringBuffer insert(int offset, String str)

在offset位置插入:八种基类类型 & String类型 & Object类型数据

StringBuffer deleteCharAt(int index)

删除index位置字符

StringBuffer delete(int start, int end)

删除[start, end)区间内的字符

StringBuffer replace(int start, int end, String str)

将[start, end)位置的字符替换为str

String substring(int start)

从start开始一直到末尾的字符以String的方式返回

String substring(int start,int end)

将[start, end)范围内的字符以String的方式返回

StringBuffer reverse()

反转字符串

String toString()

将所有字符按照String的方式返回

public static void main(String[] args) {
    StringBuilder sb1 = new StringBuilder("hello");
    StringBuilder sb2 = sb1;

    // 追加:即尾插-->字符、字符串、整形数字
    sb1.append(' '); // hello
    sb1.append("world"); // hello world
    sb1.append(123); // hello world123
    System.out.println(sb1); // hello world123
    System.out.println(sb1 == sb2); // true
    System.out.println(sb1.charAt(0)); // 获取0号位上的字符 h
    System.out.println(sb1.length()); // 获取字符串的有效长度14
    System.out.println(sb1.capacity()); // 获取底层数组的总大小
    sb1.setCharAt(0, 'H'); // 设置任意位置的字符 Hello world123
    sb1.insert(0, "Hello world!!!"); // Hello world!!!Hello world123
    System.out.println(sb1);
    System.out.println(sb1.indexOf("Hello")); // 获取Hello第一次出现的位置
    System.out.println(sb1.lastIndexOf("hello")); // 获取hello最后一次出现的位置
    sb1.deleteCharAt(0); // 删除首字符
    sb1.delete(0,5); // 删除[0, 5)范围内的字符

    String str = sb1.substring(0, 5); // 截取[0, 5)区间中的字符以String的方式返回
    System.out.println(str);
    sb1.reverse(); // 字符串逆转
    str = sb1.toString(); // 将StringBuffer以String的方式返回
    System.out.println(str);
}

从上述例子可以看出:String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。

注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

  • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
  • StringBuilder变为String: 调用toString()方法。

3.2 面试题

1. String、StringBuffer、StringBuilder的区别

  • String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  • StringBuffer与StringBuilder大部分功能是相似的
  • StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

2. 以下总共创建了多少个String对象【前提不考虑常量池之前是否存在】

String str = new String("ab"); // 会创建2个对象
String str = new String("a") + new String("b"); // 会创建4个对象

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

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

相关文章

程序员如何“升级打怪”?我用了这几个“歪瓜”!

不会吧&#xff1f;不会吧&#xff1f;计算机本命专业出身、以及半路出家的&#xff0c;混了几年了&#xff0c;还在新手村&#xff1f;对得起这几年摸的鱼&#xff1f; 思考一下&#xff1a;如何从小白一跃为大师&#xff0c;从此走上人生巅峰、迎娶白富美&#xff1f;变强只…

ArcGIS如何处理并加载Excel中坐标数据?

做GIS行业的各位肯定免不了跟数据打交道&#xff0c;其中数据的处理说复杂也复杂&#xff0c;因为我们要花时间去做数据的转换及调整工作&#xff0c;那说简单也简单&#xff0c;因为我们有很多的工具可以使用&#xff0c;那么今天我就给大家带来处理Excel中的GIS数据中的其中一…

时间序列预测(9) — Informer源码详解与运行

目录 1 源码解析 1.1 文件结构 1.2 mian_informer.py文件 1.3 模型训练 1.4 模型测试 1.5 模型预测 2 Informer模型 2.1 process_one_batch 2.2 Informer函数 2.3 DataEmbedding函数 2.4 ProbAttention稀疏注意力机制 2.5 Encoder编码器函数 2.6 Decoder解码器函数…

2023.11.20 关于 Spring MVC 详解

目录 MVC 工作流程 Spring MVC 掌握三个功能 创建 Spring MVC 项目 推荐安装插件 EditStarters 安装步骤 使用方法 实现连接功能 基础注解 RequestMapping 指定 GET 和 POST 方法类型 ResponseBody 获取参数 传递 单个 或 多个参数 参数重命名 RequestParam …

【优秀毕设】基于vue+ssm+springboot的网上购物商城系统设计

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;网上商城购物系统当然也不能排除在外。网上商城购物系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方…

k8s无法删除pv,pvc问题

问题&#xff1a; 在k8s里面创建了pv&#xff0c;pvc删除时报错&#xff1a;error: resource(s) were provided, but no name was specified 解决&#xff1a; 正确的删除顺序&#xff1a;1.先删除pod2.再删除pv 3.在删除pvc 删除pv&#xff0c;pvc命令&#xff1a; kubect…

关于“计算机中由于找不到msvcr120.dll,无法继续执行代码5种解决方法

今天&#xff0c;我想和大家分享一下关于“由于找不到msvcr120.dll,无法继续执行代码5种解决方法”的话题。在我们日常的使用中&#xff0c;有时候会遇到这样的问题&#xff1a;在运行某个程序时&#xff0c;突然提示“无法继续执行代码&#xff0c;因为找不到msvcr120.dll”。…

【VRTK】【VR开发】【Unity】6-设置interactor和虚拟手

【概述】 本篇先了解什么是interactor,什么是interactable。接着开始实操设置VRTK提供的默认控制器模型,其实就是两个长方体。接下来将长方体更换成更沉浸的带动画动作的虚拟手。最后则是介绍如何自由设置自定义手。 【Interactor和Interactable】 Interactor:互动动作的…

预约线上发布会 | “星星之火”精彩观点抢先看

11 月 17 日&#xff0c;北京市星辰天合科技股份有限公司&#xff08;简称&#xff1a;XSKY星辰天合&#xff09;在北京首钢园举办了主题为“星星之火”的 XSKY 星海全闪架构暨星飞存储发布会&#xff0c;到场嘉宾共同见证了全新的分布式全闪架构“星海&#xff08;XSEA&#x…

QTableView表头Header增加复选框Checkbox

原文出处&#xff1a;Qt 之 QHeaderView 添加复选框_qtableview添加复选框-CSDN博客 这哥们只贴了部分代码&#xff0c;我还是把它弄好分享给大家吧 DTableHeaderView.h #ifndef DTABLEHEADERVIEW_H #define DTABLEHEADERVIEW_H#include <QHeaderView>class DTableHea…

【Sql】sql server还原数据库的时候,提示:因为数据库正在使用,所以无法获得对数据库的独占访问权。

【问题描述】 sql server 还数据库的时候&#xff0c;提示失败。 点击左下角进度位置&#xff0c;可以得到详细信息&#xff1a; 因为数据库正在使用&#xff0c;所以无法获得对数据库的独占访问权。 【解决方法】 针对数据库先后执行下述语句&#xff0c;获得独占访问权后&a…

Cypress环境变量

Cypress环境变量 baseUrl 当你配置了 baseUrl &#xff0c;测试套件中的 cy.visit() 、 cy.request() 都会自动以 baseUrl 的值作为前缀并且&#xff0c;当你需要访问某些网址或者发起接口请求时&#xff0c;在代码中就可以不用再指定请求的 host 或者 url 了 如何配置 base…

安装向量数据库milvus及其Attu

前置条件安装docker compose 在宿主机上创建文件目录 mkdir -p /home/sunyuhua/milvus/db mkdir -p /home/sunyuhua/milvus/conf mkdir -p /home/sunyuhua/milvus/etcd下载docker-compose.yml wget https://github.com/milvus-io/milvus/releases/download/v2.2.11/milvus-s…

树与二叉树堆:树

目录 树&#xff1a; 树的概念&#xff1a; 树的相关概念&#xff1a; 1、结点的度&#xff1a; 2、叶节点&#xff1a;度为0的节点 3、非终端节点或分支节点&#xff1a; 4、父节点和子节点&#xff1a; 5、兄弟节点&#xff1a; 6、树的度&#xff1a; 7、树的层次或…

电脑监控系统是如何支持远程监控的?

电脑监控系统支持远程监控的方式有多种&#xff0c;以下是其中几种常见的方法&#xff1a; 远程桌面协议 这是一种常见的远程监控协议&#xff0c;它允许用户通过互联网远程访问和控制被监控的电脑。RDP是一种加密的协议&#xff0c;可以保证数据传输的安全性和隐私性。使用RD…

人性化的微距LED显示屏备受欢迎

近年来&#xff0c;微距LED显示屏市场需求不断攀升&#xff0c;尤其是LED显示屏厂商不断推陈出新的COB和Mini LED封装技术&#xff0c;价格逐渐趋于亲民。随着智慧城市的崛起&#xff0c;微距LED显示屏成为市场上备受瞩目的热门产品。伴随LED显示屏厂商不断升级产品&#xff0c…

对象方法总结-遍历

遍历对象&#xff1a; // 以对象 { protokey: proto-key } 作为原型创建一个新对象 let obj Object.create({protoKey: proto-key }); // 给新对象自身添加属性 obj.user ostuthere; obj.age 20; obj.gender female; // 添加Symbol属性 obj[Symbol(mother)] user1; obj[S…

苍穹外卖遇到的问题—员工分页查询

项目场景&#xff1a; 系统中的员工很多的时候&#xff0c;如果在一个页面中全部展示出来会显得比较乱&#xff0c;不便于查看&#xff0c;所以一般的系统中都会以分页的方式来展示列表数据。而在我们的分页查询页面中, 除了分页条件以外&#xff0c;还有一个查询条件 “员工姓…

共享内存的创建和映射过程

消息队列、共享内存、信号量的机制&#xff1a;它们在使用之前都要生成 key&#xff0c;然后通过 key 得到唯一的 id&#xff0c;并且都是通过 xxxget 函数。在内核里面&#xff0c;这三种进程间通信机制是使用统一的机制管理起来的&#xff0c;都叫 ipcxxx。为了维护这三种进程…

fractional Brownian Motion driven stochastic integrals

See https://mathoverflow.net/questions/304366/fractional-brownian-motion-driven-stochastic-integrals