带你走进Java字符串的小世界

news2024/12/25 10:25:35

目录

一. String

1. 什么是String

2. String常用构造器

3. 字符串的判断

4. 字符串的获取

5. 字符串的转换

6. 字符串比较和替换

7. 字符串的切割

二. StringBuffer与StringBuilder

2.1 关于StringBuffer

2.1.1 定义

2.1.2 构造方法

2.2 关于StringBuffer

三. StringJoiner的使用

四. 关于常量池的面试


🐼个人主页爪哇斗罗

🐼博主介绍一名打工人

🐼签名:圣人之道,为而不争。

🐼一起交流,一起进步,一起互动。

在这里插入图片描述

一. String

1. 什么是String

首先,String属于引用数据类型,而不是基本数据类型。它是用来存储字符串的,使用双引号括起来的Unicode字符序列。

每个用双引号""括起来的都是属于String的一个实例。

String str = "hello"

阅读源码(Java8)会发现,String实现Serializable接口,表示字符串可以被序列化。

同时还实现Comparable接口表示字符串可以比较大小。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];// ①
}

标注①可看出Java使用char[]来存储字符串的值,Java9以后使用byte[]存储字符串。由此说明Sting底层实际上是一个字符数组

所以上述的"hello"实际上存的是['h','e','l','l','o']。

除此之外,计算机并不会存储像h,e甚至是中文这样的字符,此时就和编码表也就是字符集有关系。

指定不同的字符集,程序底层会将对应的字符按照对应的编码表进行编码存储至内存或者磁盘中。

常见的字符集编码有utf8,GBK等。utf8一个字符对应三个字节,GBK一个字符对应两个字节

2. String常用构造器

String()构造一个空的字符串
String(byte[] arr)将字节数组转换为字符串
String(byte[] arr, int offset, int lengh)将字节数组部分转换为字符串
String(char[] arr)将char字节数组转换为字符串
String(char[] arr, int offset, int length)将char字节数组部分转换为字符串
String(String original)字符串常量构建字符串
String(byte bytes[], int offset, int length, Charset charset)将字节数组部分转换为指定字符集的字符串
byte[] b = {97,98,99,100};	
String str = new String(b);
System.out.println(str);//abcd

byte数组转换为String字符串会有一个解码的过程,就是将b存入内存中然后进行解码输出对应字符串得到abcd。

public String(byte bytes[], int offset, int length) {
    checkBounds(bytes, offset, length);
    // 解码
    this.value = StringCoding.decode(bytes, offset, length);
}

char数组转String字符串方式都和上述大同小异,这里不在赘述。

3. 字符串的判断

boolean equals(Object obj)判断两个字符串内容是否相等
boolean equalsIgnorecase(String str)忽略大小写判断两个对象是否相等
boolean contains(String str)判断大字符串是否包含小字符串
​​​​​​boolean ​startsWith(String str)判断是否以指定的字符串开头
boolean endsWIth(String str)判断是否以指定的字符串结尾
boolean isEmpty()判断字符串是否为空
public static void main(String[] args) {
    String s1 = "abcde";
    String s2 = "AbCde";
    String s3 = "abcde";
    //equals(): 比较两个字符串是否相等。
    System.out.println(s1.equals(s2));//true
    System.out.println(s1.equals(s3));//false
    //equalsIgnoreCase():忽略大小写比较字符串相等。
    System.out.println(s1.equalsIgnoreCase(s2));//true
    System.out.println(s1.equalsIgnoreCase(s3));//true
    //contains():是否包含指定字符串。
    System.out.println(s1.contains("bd"));//false
    //startsWith():是否以指定字符串开头
    System.out.println(s1.startsWith("ab"));//true
    // 第二个参数表示在索引为2的字符开始比较
    System.out.println(s1.startsWith("cde",2));//true
    //是否以字符串结尾
    System.out.println(s1.endsWith(s3));//true
    //是否为空
    System.out.println(s1.isEmpty());//false
}

4. 字符串的获取

length()获取字符串的长度
charAt(inx index)获取某个索引的字符
indexOf(int ch)获取指定字符在字符串第一次出现的位置,可以写对应的ASCALL码值
indexOf(int ch, int fromIndex)获取从指定的索引开始,字符出现的位置
indexOf(String str)获取指定的字符串在原字符串的位置
indexOf(String str, int fromIndex)获取从指定的索引开始,字符串第一次出现的位置
lastIndexOf(int ch)获取指定字符最后一次出现的索引值
lastIndexOf(String str,int fromIndex)获取指定字符串最后出现的索引值
subString(int start)从指定位置开始截取字符串
subString(int start, int end)从指定位置到指定位置截取字符串
public static void main(String[] args) {
    String str = "abcdeababcdacaeca";
    //长度
    System.out.println(str.length());//17
    //获取某个索引的字符
    System.out.println(str.charAt(1));//b
    //获取最后一个元素值
    System.out.println(str.charAt(str.length() - 1));//a
    //获取'a'第一次出现的索引值
    System.out.println(str.indexOf('a'));//0
    System.out.println(str.indexOf(97));//0
    //从第二个索引值开始,'a'第一次出现的位置
    System.out.println(str.indexOf('a', 2));//5
    //获取"bc"第一次出现的索引值
    System.out.println(str.indexOf("bc"));//1
    //从2索引开始"ad"第一次出现的索引值
    System.out.println(str.indexOf("ad", 2));//-1
    //获取'a'最后一次存储的索引值
    System.out.println(str.lastIndexOf('a'));//16
    //获取'bc'最后一次出现的索引值
    System.out.println(str.lastIndexOf("bc"));//8
    //从7索引结束前获取'a'最后一次索引值
    System.out.println(str.lastIndexOf('a', 7));//7
    System.out.println(str.lastIndexOf('c', 6));//2
    //从索引5截取到末尾
    String s1 = str.substring(5);
    System.out.println(s1);//ababcdacaeca
    //"abcdeabca" ===> "deab"
    String s2 = str.substring(3, 7);
    System.out.println(s2);
}

注意:如果没有找到都会返回-1

5. 字符串的转换

byte[] getBytes()将字符串转换为字节数组
byte[] getBytes(String charset)通过指定的字符集,将字符串转成字节数组
char[] toCharArray()将字符串转成字符数组
static valueOf(char[] chs)将字符数组转成字符串
static valueOf(Object obj)将任意的引用数据转成字符串
toLowerCase()转成小写
toUpperCase()转成大写
concat(String str)字符串连接
trim()去除两边空格
public static void main(String[] args) {
    String s = "Ab三上悠亚";
    //String转为byte[]
    byte[] bys =s.getBytes();
    //[65, 98, -28, -72, -119, -28, -72, -118, -26, -126, -96, -28, -70, -102]
    System.out.println(Arrays.toString(bys));
    //String转为char[]
    char[] c = s.toCharArray();
    //[A, b, 三, 上, 悠, 亚]
    System.out.println(Arrays.toString(c));
    //其它大部分类型转String
    System.out.println(String.valueOf(100));//100
    System.out.println(String.valueOf(false));//false
    System.out.println(String.valueOf('a'));//a
    System.out.println(String.valueOf(3.23f));//3.23
    System.out.println(String.valueOf(c,0,3));//Ab三 从0索引开始截取三个字符
    char[] data = {'A','B','c'};
    System.out.println(String.valueOf(data));//ABc
    System.out.println(s.toLowerCase());//ab三上悠亚
    System.out.println(s.toUpperCase());//AB三上悠亚
}

6. 字符串比较和替换

replace(char old, char new)新的字符替换旧的字符
replace(String old, Stringnew)新的字符串替换旧的字符串
String replace(CharSequence target, CharSequence replacement)替换指定的字符序列
int compareTo(String str)字典比较字符串
int compareToIgnoreCase(String str)忽略大小写比较
public static void main(String[] args) {
    String s = "abc三上悠亚abc";
    //b替换B 字符替换
    String s1 = s.replace('b', 'B');
    System.out.println(s1);//aBc三上悠亚aBc
    //三上悠亚替换为JAPAN字符串替换
    String s2 = s.replace("三上悠亚", "JAPAN");
    System.out.println(s2);//abcJAPANabc
    //替换指定的字符序列
    String s4 = "abc";
    String s5 = "abcd";
    String s6 = s.replace(s4, s5);
    System.out.println(s6);//abcd三上悠亚abcd
}

7. 字符串的切割

String[] split(String regex, int limit)将字符串按照某种方式进行分割并指定分割多少
String[] split(String regex)将字符串按照某种方式进行分割
public static void main(String[] args) {
    String str = "1-2-3-4-5";
    // 按照规则来切割字符串
    String[] split1 = str.split("-");
    // 按照规则来切割几段字符串
    String[] split2 = str.split("-",2);
    // [1,2,3,4.5]
    System.out.println(Arrays.toString(split1));
    // [1,2-3-4-5]
    System.out.println(Arrays.toString(split2));
}

二. StringBuffer与StringBuilder

2.1 关于StringBuffer

2.1.1 定义

作为线程不安全的可变字符序列,StringBuilder类似于String的字符缓冲区,可以看做是一个高级的String。

与String的区别就是,它是一个可变的字符序列。记住:StringBuilder是线程不安全的!!!所以在多线程场景下不可使用。

2.1.2 构造方法

StringBuilder构造

  • StringBuilder():空的构造,底层默认创建容量为16的字符缓冲区对象。
  • StringBuilder(int capacity):可以指定容量创建StringBuilder对象。
  • StringBuilder(String str):创建指定字符串的StringBuilder对象。
    StringBuilder sb = new StringBuilder();
    System.out.println(sb);//空
    System.out.println(sb.length());//0
    System.out.println(sb.capacity());//16

    StringBuilder sb1 = new StringBuilder(100);
    System.out.println(sb1);//空
    System.out.println(sb1.length());//0
    System.out.println(sb1.capacity());//100

    StringBuilder sb3 = new StringBuilder("java");
    System.out.println(sb3);//java
    System.out.println(sb3.length());//4
    System.out.println(sb3.capacity());//20

StringBuilder成员方法

  • 增加功能

    • String append(Object obj):括号中可以是任意类型

    • insert(int offset, String str):任意地方添加指定类型

  • 删除功能

    • deleteCharAt(int index) 指定位置删除对应的元素
    • delete(int index, int end)删除[index,end-1]之间的元素
  • 修改功能:

    • setCharAt(int n, char ch):
    • replace(int start,int end,String str):
  • 查询功能

    • charAt(int n):
    • int Capacity():
    • int length():
  • 反转功能

    • reverse() 反转功能
  • 截取功能

    • String substring(int start):截取指定位置一直到末尾
    • String substring(int start,int end):截取[start,end-1]范围
StringBuilder sb = new StringBuilder();
//添加
sb.append('j').append("av").append(false).append(100);//javfalse100
sb.insert(1, false);//jfalseavfalse100
//删除
sb.deleteCharAt(0);//删除第一个字符 falseavfals100
sb.delete(0, 3);//删除[0-2]的字符  seavfals100
//修改
sb.setCharAt(3, 't');//seatfalse100
sb.replace(3,7,"true");//seatruelse100
//查询元素
System.out.println(sb.charAt(6));//e
System.out.println(sb.length());//12
System.out.println(sb.capacity());//初始容量16
//截取功能
System.out.println(sb.substring(3));//truelse100
System.out.println(sb.substring(4, 7));//rue 截取[4,6]        

2.2 关于StringBuffer

StringBuffer与StringBuilder的用法是一模一样的,这里不再赘述相关方法,主要对比他们两有什么区别。

常见的String,StringBuffer,StringBuilder的面试题。

  • 可变性

    • String用final修饰,不可变
    • StringBuffer与StringBuilder都是继承AbstratBuilder类,存储的char[]并未用final修饰,是可变的
  • 线程安全性

    • String对象不可变,可以视为线程安全
    • StringBuffer加了同步锁,线程安全
    • StringBuilder方法未加同步锁,线程不安全
  • 性能

    • 每次对String进行赋值时都会产生新对象,然后将指针指向新的对象。
    • StringBuffer每次都会对对象的本身进行操作,而不是产生新的对象去引用它,相同情况下,使用StringBuilder的性能会提高,但是会有线程不安全的风险。

代码比较StringBuilder与StringBuffer的性能:

    private static void demo02() {
		StringBuilder sb = new StringBuilder("abc");
        //当前时间
		long l1  = System.currentTimeMillis();
		for(int i=0; i<100000;i++) {
			sb.append("hello");
		}
        //跑完循环
		long l2  = System.currentTimeMillis();
		System.out.println("String连接耗时:"+ (l2 -l1));
	}
    private static void demo01() {
		String s = "abc";
		//当堆空间溢出会发生OutOfMemoryError
        //当前时间
		long l1  = System.currentTimeMillis();
		for(int i=0; i<100000;i++) {
			s += "hello";
		}
        //跑完循环
		long l2  = System.currentTimeMillis();
		System.out.println("String连接耗时:"+ (l2 -l1));
	}

如何使用三者?

  • 操作少量的数据:String
  • 单线程操作大量数据:StringBuilder
  • 多线程操作大量数据:StringBuffer

三. StringJoiner的使用

上面,我们总是使用SpringBuilder去拼接字符串,使用的分割符号很多。

并且代码量相对来说也是比较多的,Java1.8给我们提供了一个StringJoiner类来专门拼接字符串。

先看一个简单的例子,将集合中的元素通过逗号分割开并输出一个字符串:

public static void main(String[] args) {
	List<Integer> integers = new ArrayList<Integer>();
	integers.add(1);
	integers.add(2);
	integers.add(3);
	integers.add(4);
	integers.add(5);
	StringBuilder stringBuilder = new StringBuilder();
	for (Integer integer : integers) {
		stringBuilder.append(integer + ",");
	}
	// 1,2,3,4,5
	System.out.println(stringBuilder.toString().substring(0, stringBuilder.length() - 1));
	}

这样的代码是不是看起来繁杂,并且只能通过手动去拼接,如果使用StringJoiner去拼接字符串就会一步到位:

public static void main(String[] args) {
	List<Integer> integers = new ArrayList<Integer>();
	integers.add(1);
	integers.add(2);
	integers.add(3);
	integers.add(4);
	integers.add(5);	
	// 序号1
	StringJoiner stringJoiner = new StringJoiner(",");
	for (Integer integer : integers) {
		stringJoiner.add(String.valueOf(integer));
	}
	// 1,2,3,4,5
	System.out.println(stringJoiner.toString());
	}

以上两段代码输出的结果都是一样的,都是1,2,3,4,5,如果我们需要输出这样的字符串[1,2,3,4,5]怎么办?其实StringJoiner也提供了这样的方法,只需要将上述的序号1代码换成:

StringJoiner stringJoiner = new StringJoiner(",","[","]");

添加两个参数,分别代表的是前缀与后缀,是不是非常简单呢,这个在开发中也是很常用的。

如果获取的数据是空的,我们呢又要给其设置一个默认的值。

那么可以使用setEmptyValue()方法就可以了:

stringJoiner.setEmptyValue("1");

拼接字符串使用StringJoiner还是挺方便的,赶快用起来吧!

四. 关于常量池的面试

先看如下所示的代码:s1与s2相等吗?

String s1 = new String(abc");
String s2 = "abc";

s1与s2虽然内容都是一样,但是两者是不相等的。

因为String是引用数据类型,如果比较相等(==),两者比较的是地址与内容是否相等。这就会引出常量池的概念。

s1是引用对象,首先会在栈内存中会开辟一个s1的引用对象的空间,而abc这个字符串常量是存在方法区常量池中。通过s1这个对象引用指向abc。

s2则是s2的一个引用指向了abc。

注意:JDK1.7之前,常量池在方法区中,JDK1.7及以后常量池放在了堆里面,我们通常指的的是1.7之前的常量池

下面来看==与equals()的比较字符串是否相等的使用。

  • == 比较的地址和内容都相等才相等
  • equals()内容相等即是相等

理解上面两句,看如下代码就会清晰很多:

    String s1 = "123";①
    String s2 = "123";②
    String s3 = new String("123");③
    System.out.println(s1==s2);//正确
    System.out.println(s1==s3);//错误

只要明白了内存分布,判断不成问题。对于①,②来说,s1,s2都在栈内存中。

对于③来说,会先在栈中开辟一个内存空间存放引用对象s3。

然后会在堆内存中重新开辟空间存放new String("123")中的String匿名对象的值123所以s1==s3是错误的!!!

对于equals()就不一样了比较的是内容是否相等,三者内容都是相等的,所以equals是true

PS: null," "的区别

null代表的是空对象,并不是字符串,可以赋给任何对象,字符串中表示只是一个引用,还没有内存空间的分配

“ ”表示引用已经指向了 一块内存空间了,是一个实际的东西,可以进行操作了,表示一个长度为0的字符串

练习一:

String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3==s4);
System.out.println(s3.equals(s4));
String s5 = "hello";
String s6 = "hello";
System.out.println(s5==s6);
System.out.println(s5.equals(s6));

答案:F T F T T T

关于字符串的拼接

  • 常量与常量的拼接还在常量池中
  • 常量池不可有相同的常量
  • 拼接的时候,只要存在变量都会存到堆中
  • 调用intern()方法返回常量池里面的常量
    String s1 = "hello";
    String s2 = "world";
    String s3 = "helloworld";
    System.out.println(s3==(s1+s2));//F 变量的连接存在堆中不相等
    System.out.println(s3==(s1+s2).intern());//T 获取的是值相等
    System.out.println(s3.equals(s1+s2));//T 获取内容相等
    System.out.println(s3=="hello" + "world");//T 常量与常量连接还在常量池中
    System.out.println(s3.equals("hello"+"world"));//T	内容相等	

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

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

相关文章

分布式缓存的四大痛点

目前开发中经常用到的缓存&#xff0c;是我们必不可缺的&#xff0c;他大大的提高了我们整个项目的响应速度和并发量。但是带来好处的同时&#xff0c;也给我们带了了新的问题&#xff1a;缓存穿透、缓存击穿、缓存雪崩以及缓存一致性这么四个问题&#xff0c;也是分布式缓存的…

LeetCode算法之----动态规划

点赞收藏&#xff0c;以防遗忘 本文【程序大视界】已收录&#xff0c;关注免费领取互联网大厂学习资料&#xff0c;添加博主好友进群学习交流&#xff0c;欢迎留言和评论&#xff0c;一起交流共同进步。 目录 【一】前言 【二】打家劫舍 【三】不同路径 【四】最小路径和 …

【数据预处理】基于Kettle的字符串数据清洗、Kettle的字段清洗、Kettle的使用参照表集成数据

文章目录一.前言1.1 实验内容二.实验过程2.1 实验内容一&#xff1a;掌握基于Kettle的字符串数据清洗2.2 实验内容二&#xff1a;掌握基于Kettle的字段清洗2.3 实验内容三&#xff1a;掌握基于Kettle的使用参照表集成数据2.4 实验心得&#xff1a;一.前言 需要本文章的源文件下…

用零知识证明连接多链宇宙

目录 一、前言 二、Bridges和Zero Knowledge Proofs 三、Succinct Verification of Proof of Consensus (Succinct Labs)

【自然语言处理】【ChatGPT系列】ChatGPT的智能来自哪里?

相关博客 【自然语言处理】【ChatGPT系列】ChatGPT的智能来自哪里&#xff1f; 【自然语言处理】【ChatGPT系列】Chain of Thought&#xff1a;从大模型中引导出推理能力 【自然语言处理】【ChatGPT系列】InstructGPT&#xff1a;遵循人类反馈指令来训练语言模型 【自然语言处理…

二叉搜索树与Mysql索引的亲密关系

欢迎关注公众号&#xff1a;【离心计划】&#xff0c;一起逃离技术舒适圈 二叉搜索树 二叉搜索树大家应该多多少少听过&#xff0c;它有一个很重要的特征&#xff0c;就是父节点左子树所有结点的值小于父节点的值&#xff0c;右子树所有结点的值大于父节点的值&#xff0c;这个…

详解vue中vuex的用法

前言 说到 vuex 相信大家都不陌生&#xff0c;vuex 是一个专为 vue.js 应用程序开发的状态管理模式。vuex 背后的基本思想&#xff0c;就是单向数据流。今天我们就来好好聊聊 vuex。 vuex&#xff1f; 用官方的话来说&#xff0c;vuex 是一个专为 vue.js 应用程序开发的状态管…

【Linux】进程间通信之共享内存与信号量初识

目录&#x1f308;前言&#x1f338;1、System V共享内存&#x1f361;1.1、概念&#x1f362;1.2、原理&#x1f33a;2、共享内存相关函数和指令&#x1f361;2.1、shmget函数&#xff08;创建&#xff09;&#x1f362;2.2、shmctl函数&#xff08;控制&#xff09;&#x1f…

使用 DataAnnotations(数据注解)实现模型的通用数据校验

DataAnnotations 实现数据模型的通用校验参数校验的意义常用参数的校验.NET 中内置 DataAnnotations 提供的特性校验关于 DataAnnotations 中的特性介绍基于 DataAnnotations 的通用模型校验封装基于 DataAnnotations 的特性校验助手实现步骤如何使用 DataAnnotations 封装的特…

某农业学校 算法设计与分析-第五次实验-回溯算法

1. 罗密欧与朱丽叶的迷宫问题 问题描述 罗密欧与朱丽叶的迷宫。罗密欧与朱丽叶身处一个mn的迷宫中&#xff0c;如图所示。每一个方格表示迷宫中的一个房间。这mn个房间中有一些房间是封闭的&#xff0c;不允许任何人进入。在迷宫中任何位置均可沿8 个方向进入未封闭的房间。罗…

第二章:关系数据库

一、关系数据库结构及形式化定义 1、【单选题】 下图中&#xff0c;关系D1、D2、D3笛卡尔积的目和基数分别为 正确答案&#xff1a; B 2、【多选题】下图中能够作为候选码的属性组为 正确答案&#xff1a; ABD 3、【多选题】关于关系数据库&#xff0c;说法正确的是 正确答…

二、栈和队列

二、栈和队列 栈——后进先出 应用&#xff1a;数制转换、括号匹配、行编辑程序、迷宫求解、表达式求值、八皇后问题、函数调用、递归调用的实现 队列——先进先出 应用&#xff1a;脱机打印输出 多用户系统用户排队分时循环使用CPU和主存 按用户优先级排队&#xff0c;每…

编译gtest报错‘is_trivially_copy_constructible’ is not a member of ‘std’

编译gtest报错‘is_trivially_copy_constructible’ is not a member of ‘std’一、问题描述二、原因分析三、升级gcc版本四、验证一、问题描述 在一个新的Redhat7.6 linux虚拟机上&#xff0c;将gtest clone下来之后编译&#xff0c;一堆报错&#xff1a; /opt/googletest/…

多线程问题(二)(安全问题)

目录 一、多线程不安全引例 二、线程不安全的原因 1、线程是抢占式执行 2、多线程共享同一变量 3、对变量的操作不是原子性 4、内存可见性 5、指令重排序 三、线程不安全问题的解决方案 1、使用synchronized关键字进行加锁 a、 synchronized修饰普通方法 b、sy…

Maleimide-PEG-Biotin,Biotin-PEG-MAL,生物素PEG马来酰亚胺用于生物分子检测

化学试剂生物素聚乙二醇马来酰亚胺&#xff0c;其英文名为Maleimide-PEG-Biotin&#xff0c;Biotin-PEG-MAL&#xff0c;它所属分类为Biotin PEG Multi-arm PEGs。 该试剂质量控制为95%&#xff0c;试剂的储存条件为&#xff1a; -20℃长期保存&#xff0c;避光&#xff0c;干…

数据结构---图

&#xff08;一&#xff09; 相关知识点 图&#xff08;graph&#xff09;&#xff1a;图是由顶点的有穷非空集合和顶点之间边的集合组成&#xff0c;通常表示为&#xff1a;G(V,E)&#xff0c;其中&#xff0c;G表示一个图&#xff0c;V是图G中的顶点的集合&#xff0c;E是图G…

SpringBoot系列之自动装配原理详解

文章目录前言一、SpringBoot自动配置-Condition-11、观察spring自动创建bean过程2、创建自定义bean对象3、根据条件创建自定义bean二、 SpringBoot自动配置-Condition-2三、SpringBoot自动配置-切换内置web服务器1、查看继承关系图2、shiftdelete 排除Tomcat四、SpringBoot自动…

Win10启动Pycharm报错

Win10启动Pycharm报错报错信息解决方法报错信息 Internal error. Please report to http://jb.gg/ide/critical-startup-errors java.net.BindException: Address already in use: bind at java.base/sun.nio.ch.Net.bind0(Native Method) at java.base/sun.nio.ch.Net.bind(U…

如何在3个月内写出博士论文

在阅读本文之前&#xff0c;请注意&#xff1a;我花了三年半的时间进行全职研究&#xff0c;为我的博士论文收集数据&#xff1b;这三个月只涉及写作&#xff0c;我在最后很快就完成了。我并不是说每个人都能写得那么快&#xff0c;如果你没有做过研究&#xff0c;那是不可能的…

全国各省368个地级市河流密度数据(工具变量)

数据来源&#xff1a;国家基础地理信息中心 时间跨度&#xff1a;-- 区域范围&#xff1a;全国各省市 指标说明&#xff1a; 根据河流矢量和中国城市行政边界矢量地理信息&#xff0c;计算每个城市河流的总长度&#xff1b;根据各城市的行政区划面积&#xff0c;计算中国各城…