字符串类String8

为什么一个“时间片”能折腾 Linux 十年? 时间片扩展不是抢占调度器的控制权,也不是提升优先级。在“非常短暂、非常确定”的用户态临界区内,避免线程被不必要地抢占。用户态自旋锁(user-space spinlock)无系统调用的极短临界区高并发、低延迟的数据结构操作RSEQ(Restartable Sequences)保护区间一旦线程在临界区被抢占,系统整体性能反而下降。线程 A 拿着一个用户态锁线程 B 被调度上来,开始自旋等这个锁但 A 因为时间片用完,被调度器切走CPU 白白空转,所有线程都在浪费时间。 阅读详情

仿Android 工具类String8写的

/*************************************************************************
    > File Name: string8.h
    > Author: hsz
    > Mail:
    > Created Time: 2021年04月11日 星期日 12时24分52秒
 ************************************************************************/

#ifndef __STRING8_H__
#define __STRING8_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <stdarg.h>
#include <stdint.h>
#include <ctype.h>

namespace Alias {

#define MAXSIZE (1024 * 8)

class String8 {
public:
                        String8();
                        String8(const String8& other);
                        String8(const char* other);
                        String8(const char* other, const size_t numChars);
                        String8(const std::string& other);

                        ~String8();

    const char*         c_str() const;
    std::string         toStdString() const;           // String8 -> std::string

    bool                isEmpty() const;
    size_t              length() const;
    void                clear();

    int                 append(const String8& other);
    int                 append(const char* other);
    int                 append(const char* other, size_t numChars);
	// this只能用于非静态成员函数,所以第一个参数就是fmt
    static String8      format(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
    // 类成员函数第一个参数是隐藏的this指针   
    int                 appendFormat(const char* fmt, ...) __attribute__((format (printf, 2, 3)));  

    String8&            operator=(const String8& other);
    String8&            operator=(const char* other);

    String8&            operator+=(const String8& other);
    String8             operator+(const String8& other) const;

    String8&            operator+=(const char* other);
    String8             operator+(const char* other) const;

    int                 compare(const String8& other) const;
    int                 compare(const char* other) const;
    // if == return 0;
    int                 StrCaseCmp(const String8& other) const;
    int                 StrCaseCmp(const char* other) const;

    bool                operator<(const String8& other) const;
    bool                operator<=(const String8& other) const;
    bool                operator==(const String8& other) const;
    bool                operator!=(const String8& other) const;
    bool                operator>=(const String8& other) const;
    bool                operator>(const String8& other) const;

    bool                operator<(const char* other) const;
    bool                operator<=(const char* other) const;
    bool                operator==(const char* other) const;
    bool                operator!=(const char* other) const;
    bool                operator>=(const char* other) const;
    bool                operator>(const char* other) const;

    // return the index of the first byte of other in this at or after
    // start, or -1 if not found
    size_t              find(const char* other, size_t start = 0) const;

    // return true if this string contains the specified substring
    bool                contains(const char* other) const;
    bool                removeAll(const char* other);

    void                toLower();
    void                toLower(size_t start, size_t numChars);
    void                toUpper();
    void                toUpper(size_t start, size_t numChars);

private:
    char*               getBuffer(size_t numChars = 0);
    void                release();
    static String8      formatV(const char* fmt, va_list args);
    int                 appendFormatV(const char* fmt, va_list args);
    void                setTo(const String8& other);
    int                 setTo(const char* other);
    int                 setTo(const char* other, size_t numChars);

private:
    char *mString = nullptr;
};

} // namespace Alias
#endif // __STRING8_H__
/*************************************************************************
    > File Name: string8.cpp
    > Author: hsz
    > Mail:
    > Created Time: 2021年04月11日 星期日 12时25分02秒
 ************************************************************************/
/*************************************************************************
    > File Name: string8.cpp
    > Author: hsz
    > Mail:
    > Created Time: 2021年04月11日 星期日 12时25分02秒
 ************************************************************************/

#include "string8.h"

namespace Alias {

char *String8::getBuffer(size_t numChars)
{
    char *ret = nullptr;
    if (numChars <= 0) {
        ret = (char *)malloc(1);
        if (ret) {
            *ret = '\0';
        }
        return ret;
    } else if (numChars > 0) {
        ret = (char *)malloc(numChars + 1);
        if (ret) {
            memset(ret, 0, numChars + 1);
        }
        return ret;
    }
}

void String8::release()
{
    if (mString == nullptr) {
        return;
    }
    free(mString);
    mString = nullptr;
}

String8::String8()
{
    mString = getBuffer();
}

String8::String8(const String8& other)
{
    if (other.length() == 0) {
        mString = getBuffer();
        return;
    }
    mString = getBuffer(other.length());
    memcpy(mString, other.mString, other.length());
}

String8::String8(const char* other)
{
    if (other == nullptr) {
        mString = getBuffer();
        return;
    }
    size_t length = strlen(other);
    mString = getBuffer(length);
    memcpy(mString, other, length);
}

String8::String8(const char* other, const size_t numChars)
{
    if (other == nullptr) {
        mString = getBuffer();
        return;
    }
    size_t length = strlen(other);
    if (length > numChars) {
        length = numChars;
    }
    mString = getBuffer(length);
    memcpy(mString, other, length);
}

String8::String8(const std::string& other)
{
    size_t length = other.length();
    mString = getBuffer(length);
    memcpy(mString, other.c_str(), length);
}

String8::~String8()
{
    release();
}
size_t String8::find(const char* other, size_t start) const
{
    const char *tmp = strstr(mString + start, other);
    return tmp ? tmp - mString : -1;
}

const char* String8::c_str() const
{
    return mString;
}

std::string String8::toStdString() const
{
    return std::string(mString);
}

bool String8::isEmpty() const
{
    return length() == 0;
}

size_t String8::length() const
{
    return strlen(mString);
}

void String8::clear()
{
    memset(mString, 0, strlen(mString));
}

int String8::append(const String8& other)
{
    return append(other.mString, other.length());
}

int String8::append(const char* other)
{
    return append(other, strlen(other));
}

int String8::append(const char* other, size_t numChars)
{
    if (other == nullptr) {
        return -1;
    }
    size_t size = strlen(other);
    if (size > numChars) {
        size = numChars;
    }
    if (size == 0) {
        return 0;
    }

    size_t totalSize = size + length();
    char *buf = getBuffer(totalSize);
    if (buf) {
        memcpy(buf, mString, length());
        memcpy(buf + length(), other, size);
        this->release();
        mString = buf;
        return size;
    }
    return 0;
}

String8& String8::operator=(const String8& other)
{
    setTo(other);
    return *this;
}
String8& String8::operator=(const char* other)
{
    setTo(other);
    return *this;
}

String8& String8::operator+=(const String8& other)
{
    this->append(other);
    return *this;
}
String8 String8::operator+(const String8& other) const
{
    String8 tmp(*this);
    tmp += other;
    return tmp;
}
String8& String8::operator+=(const char* other)
{
    this->append(other);
    return *this;
}
String8  String8::operator+(const char* other) const
{
    String8 tmp(*this);
    tmp += other;
    return tmp;
}

int String8::compare(const String8& other) const
{
    return strcmp(mString, other.mString);
}

int String8::compare(const char* other) const
{
    return strcmp(mString, other);
}

int String8::StrCaseCmp(const String8& other) const
{
    return strcasecmp(mString, other.mString);
}

int String8::StrCaseCmp(const char* other) const
{
    return strcasecmp(mString, other);
}

bool String8::operator<(const String8& other) const
{
    return strcmp(mString, other.mString) < 0;
}
bool String8::operator<=(const String8& other) const
{
    return strcmp(mString, other.mString) <= 0;
}
bool String8::operator==(const String8& other) const
{
    return strcmp(mString, other.mString) == 0;
}
bool String8::operator!=(const String8& other) const
{
    return strcmp(mString, other.mString) != 0;
}
bool String8::operator>=(const String8& other) const
{
    return strcmp(mString, other.mString) >= 0;
}
bool String8::operator>(const String8& other) const
{
    return strcmp(mString, other.mString) > 0;
}

bool String8::operator<(const char* other) const
{
    return strcmp(mString, other) < 0;
}
bool String8::operator<=(const char* other) const
{
    return strcmp(mString, other) <= 0;
}
bool String8::operator==(const char* other) const
{
    return strcmp(mString, other) == 0;
}
bool String8::operator!=(const char* other) const
{
    return strcmp(mString, other) != 0;
}
bool String8::operator>=(const char* other) const
{
    return strcmp(mString, other) >= 0;
}
bool String8::operator>(const char* other) const
{
    return strcmp(mString, other) > 0;
}

void String8::setTo(const String8& other)
{
    setTo(other.mString, other.length());
}

int String8::setTo(const char* other)
{
    return setTo(other, strlen(other));
}

int String8::setTo(const char* other, size_t numChars)
{
    if (other == nullptr) {
        return -1;
    }
    numChars = numChars > strlen(other) ? strlen(other) : numChars;

    if (strlen(mString) >= numChars) {
        memset(mString, 0, strlen(mString));
        memcpy(mString, other, numChars);
    } else { // if (strlen(mString) < other.length()) 
        release();
        mString = getBuffer(numChars);
        memcpy(mString, other, numChars);
    }
}

bool String8::contains(const char* other) const
{
    return nullptr != strstr(mString, other);
}

bool String8::removeAll(const char* other)
{
    size_t start = 0;
    if (other && ((start = find(other)) >= 0)) {
        size_t end = strlen(other) + start;
        if (end >= length()) {
            mString[start] = '\0';
            return true;
        } else {
            size_t bufferSize = length() - (end - start);
            char *newString = getBuffer(bufferSize);
            if (newString == nullptr) {
                return false;
            }
            memcpy(newString, mString, start);
            memcpy(newString + start, mString + end, length() - end);
            free(mString);
            mString = newString;
            return true;
        }
    }
    return false;
}

void String8::toLower()
{
    toLower(0, length());
}

void String8::toLower(size_t start, size_t numChars)
{
    size_t size = length();
    if (size > start) {
        for (size_t i = start; i < numChars && i < size; ++i) { // i < size -> anti overflow
            mString[i] = static_cast<char>(tolower(mString[i]));
        }
    }
}

void String8::toUpper()
{
    toUpper(0, length());
}

void String8::toUpper(size_t start, size_t numChars)
{
    size_t size = length();
    if (size > start) {
        for (size_t i = start; i < numChars && i < size; ++i) { // i < size -> anti overflow
            mString[i] = static_cast<char>(toupper(mString[i]));
        }
    }
}

String8 String8::format(const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);

    String8 result(formatV(fmt, args));

    va_end(args);
    return result;
}

String8 String8::formatV(const char* fmt, va_list args)
{
    String8 result;
    result.appendFormatV(fmt, args);
    return result;
}

int String8::appendFormat(const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);

    int numChars = appendFormatV(fmt, args);

    va_end(args);
    return numChars;
}

int String8::appendFormatV(const char* fmt, va_list args)
{
    int n;
    va_list tmp_args;
    va_copy(tmp_args, args);
    n = vsnprintf(nullptr, 0, fmt, tmp_args);
    va_end(tmp_args);

    if (n < 0) {
        return n;
    }

    if (n > 0) {
        size_t oldLength = length();
        if ((size_t)n > MAXSIZE - 1 ||
            oldLength > MAXSIZE - (size_t)n - 1) {
            return -1;
        }

        char *buf = (char *)malloc(oldLength + n);
        if (buf == nullptr) {
            return -1;
        }
        memcpy(buf, mString, oldLength);
        release();
        vsnprintf(buf + oldLength, n + 1, fmt, args);
        mString = buf;
    }
    return n;
}
} // namespace Alias

测试(未测试全)

#include <iostream>
#include <stdio.h>
#include "string8.h"

int main()
{
    Alias::String8 str1;
    str1 = "123456789";
    str1.append("abcde", 3);
    std::cout << str1.c_str() << "\n";
    str1.appendFormat(" %p", str1.c_str());
    std::cout << "ptr = " << str1.c_str() << "\n";

    str1.clear();
    str1.appendFormat("[%d.%d.%d.%d]", 192, 168, 124, 7);
    std::cout << str1.c_str() << "\n";

    Alias::String8 str2 = str1;
    str2.appendFormat(" %p", str2.c_str());
    std::cout << "str2: "<< str2.c_str() << "\n";
    std::cout << str2.find("168.124.7") << "\n";
    std::cout << str2.contains("168.124.7") << "\n";
    std::cout << str2.compare(str1) << "\n";
    str2 = "ABcdEF";
    str2.toLower();
    std::cout << "toLower str2: "<< str2.c_str() << "\n";

    Alias::String8 str3(str1);
    std::cout << "str3: "<< str3.c_str() << "\n";
    std::cout << (str3 == str2) << "\n";
    str3 = "AbcdEF";
    std::cout << str3.StrCaseCmp(str2) << "\n";
    str3.toLower();
    std::cout << "toLower str3: "<< str3.c_str() << "\n";
    std::cout << "str3 == str2 -> " << (str3 == str2) << "\n";

    str3.removeAll("abcdef");
    str3 += str2;
    std::cout << "str3: "<< str3.c_str() << "\n";
    Alias::String8 str4 = str1 + str2 + str3;
    std::cout << str4.toStdString() << std::endl;

	Alias::String8 str5 = Alias::String8::format("%s", str4.c_str());
    std::cout << str5.toStdString() << std::endl;
    return 0;
}

运行结果

SmartFusion从FPGA到ARM(一)——MSS_GPIO点灯 文章目录前言GPIO点灯 前言 GPIO点灯 阅读详情

相关推荐

量化金融笔记1-股票量化基础

股票量化基础 文章目录什么是股票股票的定义及其诞生所解决的问题股票的主体和流通股票的常规分类股票价格收益率什么是股票价格的收益率股票价格收益率计算在python中的实现两种收益率算法的特点及应用场合股票交易规则场内交易与场外交易A股、B股、H股国内多层次的资本市场股票交易指令和撮合机制股票交易时间股票交易成本股票复权股票数据介绍与提取行业分类和指数行情数据因子数据标的数据基本面数据 什么是股票 股票的定义及其诞生所解决的问题 股票的定义:股票是一种有价证券,是股份有限公司公开发行的用以证明投资者的股东身份

折桂狂人的博客 2395

android底层库libutils之string8,string16研究

在之前看android camera framework代码时,发现代码中大量使用了string8、string16类。由于之前学习的是C#,java等高级面向对象语言唯独没有认真研究过C++。所以对C++中的string比较陌生。虽然他们的用法都是一样的,但是这里还是想认真研究一下底层实现原理。

armwind的专栏 2万+

Unity XR Interaction Toolkit(二)手柄交互

XR Interaction 手柄事件和抓取设置

qq_36608844的博客 8495

C++实现字符串类型(String16/String8/const char/char)转换

C++实现字符串类型(String16/String8/const char/char)转换     最近在C++开发的时候遇到这么个问题,需要对函数参数中传来的String16参数进行大小写统一的转换,并且转换后的数据类型还是String16.下面就介绍一下各类数据类型的转换。     首先是String16到String8的转换: String16 name16 = St

☃Clay's♂Blogs 2万+

用面包板实测MOSFET:手把手教你测量跨导和开关时间

本文详细介绍了如何使用面包板、Arduino和示波器搭建测试平台,实测MOSFET的跨导和开关时间。通过分步测量流程和示波器技巧,帮助电子设计初学者深入理解MOSFET的动态特性,包括跨导计算、开关时间参数解析以及米勒平台现象分析。

beer8的博客 221

基于TDOA的chan算法(定位算法)

Chan算法原理 TDOA(TDOA,the time differences of arrival,到达时间差),Chan算法是TDOA定位方法的一个很好用的方法。 Chan算法是非递归双曲线方程组解法,具有解析表达式解,主要特点是:在测量误差服从理想高斯分布时,它的定位精度高、计算量小,并且可以通过增加已确定点的数量来提高算法精度。 该算法的推导前提是基于测量误差为零均值高斯随机变量,对于实际环境中误差较大的测量值,比如在有非视距误差的环境下,该算法的性能会有显著下降。二维情况下,可分为只有三个点参与定

优快云不再更新 2万+

C++ String16/String8与const char*及char*与vector相互转换(五十一)

1.String16转const char* String16 name16 = String16("Hello World"); String8 name8 = String8(name16); const char *buffer = name8.string(); 验证: printf("buffer = %s\n",buffer); 注意: String16.string()其实是c...

Android系统攻城狮 8763

黏菌算法(Slime Mould Algorithm,SMA)

这是一篇关于黏菌算法的总结博客,包含算法思想,算法步骤,求函数最值(Python实现),算法改进等,持续更新ing

weixin_46838605的博客 1万+

android::String8与Java String对比

【代码】android::String8与Java String对比。

performance 1117

无线自组织网络基础知识

参考书籍:《无线自组织网络路由协议及应用》 目录第一章 绪论1.1 无线自组织网络概述1.1.1 无线自组织网络的定义及分类1.1.2无线自组织网络的主要特点1.1.3无线自组织网络的应用与发展1.无线自组织网络的应用2.无线自组织网络的起源和发展1.2典型的无线自组织网络1.2.1移动Ad Hoc网络1、移动Ad Hoc网络的定义2.移动AdHoc网络的特点3.移动Ad Hoc网络的应用1.2....

逸凌Time 2万+

CosyVoice语音合成使用教程

CosyVoice是一款开源的语音合成工具,它基于深度学习模型,能够生成高度逼真的语音内容。该工具支持多种语言的语音生成,包括中文、英文、日文、粤语和韩语。CosyVoice的亮点在于它对生成语音情感和韵律的精细控制,通过富文本或自然语言输入,可以显著提升合成语音的情感表达能力。CosyVoice提供了多种预训练模型,用户可以根据需求选择合适的模型。:基底模型,适用于一般语音合成任务。:经过SFT微调的模型,适用于特定音色和情感的语音合成。:支持Instruct微调的模型,适用于自然语言控制的语音合成。

笔者从事电信媒体开发多年,愿意将多年的开发经验分享给同行 4442

C++ string(八)

#include const int SIZE = 5; using namespace std; void stringTest(); int main(int argc, const char * argv[]) { stringTest(); return 0; } void stringTest() {

爱技术....爱生活! 781

达梦数据库修改最大连接数

达梦数据库的最大连接数推荐配置与服务器内存有关。不应设置得过大,否则容易导致出现OOM。文件中整型的参数值。DSC环境下,除了特殊参数以外,其他参数值会在OK节点上同步。返回值:当前DM.INI文件中对应的参数值。功能说明:返回DM.INI文件中。:DM.INI文件中的参数名。

Sebastien23的博客 3332

Java 中的String 字符串类(8千字超全详解)

本文详细总结讲解了 String 类(字符串) 的知识,并深入解释了 String类 的注意事项和细节,举了很多很多的例子来讲解。String 类(字符串)是Java 的重难点,理解并掌握这一部分的知识,需要有较好的面向对象的基础。小白博主已经尽力整理了,希望小伙伴们看后能有所收获!最后,如果本文有什么错漏的地方,欢迎大家批评指正!一起加油!!我们下一篇博文见吧!

林二月的博客 4310

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

第十五讲 Java异常机制、自定义异常、断言调试技术、JDK8主要新特性介绍、String字符串类

导读 Java异常,是一种代码错误处理技术。 程序一旦出现异常,那么即立刻停止JVM。程序代码不会再运行了,所以每次会抛出多个异常。但同时只能捕获一个异常,并推荐程序员捕获并处理及正确反馈给用户。 自定义异常:必须要使用extends关键字去继承一个Exception类。 断言技术:一般用于程序的测试技术。 JDK8主要新特性介绍(目的在于编程的时候可以使用新的特

宁叔 1883

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

53_可变字符串类和日期相关类

可变字符串类和日期相关类 可变字符串类(重点) 基本概念 由于String类描述的字符串内容是个常量数值不可改变,当需要在Java代码中描述大量类似的字符串时,只能单独申请和存储,此时会造成内存空间和时间的浪费,因为用过一次之后就可能不再用就要销毁了。 为了解决上述问题,可以使用java.lang.StringBuilder类和java.lang.StringBuffer类来描述字符序列可以改变的字符串,如:“ab”。这个就是在一块内存空间中对类似的内容来回调整就行,就不需要大量的申请内存,释放内存等

h2806504347的博客 431

c#截取字符串后几位_基础库的字符串设计

C++在字符串上表现,一直以来很受人诟病,没有一个库的字符串类的表现能让人满意, std的string,mfc的CString,Qt的QString等等字符串类,都存在这样那样的问题,以至于字符串处理竟然成为C++的弱项,这也太不应该了。话说回来,C++对待字符串的态度也很奇葩,其他语言都将字符串当做是内建类,在编译器层面来实现,只有C++是通过库的形式来提供字符串的抽象,也就是说,C++的语言层...

weixin_32943417的博客 302

初学Java基础Day20---包装类,Integer底层,字符串类。

8种基本数据类型对应类。出现原因:Java为纯面相对象语言(万物皆对象),但8种基本数据类型不能new对象,就破坏了Java为纯面向对象语言的特征,Java又为8种基本数据类型分别匹配了对应的类,这种类叫做包装类/封装类。

2401_87491344的博客 981

【无标题】

String

qq_48984427的博客 282

java求职学习day10

可变字符串类和日期相关类

m0_64262133的博客 724

面试JAVASE基础(四)——Java 八大包装类、String 、日期类及文件操作核心类 File全解析

在 Java 编程世界里,有许多核心类在数据处理、文件操作等场景中扮演着关键角色。下面我们将详细介绍八大包装类、String及日期类,还有文件操作核心类File,帮助大家全方位掌握这些重要工具。

2302_79797878的博客 1002

80070583类不存在_Java中常见的类

知识点思维导图Object类Object类的概念类Object是类层次结构的根,也就是说任何类都是该类的直接或间接子类。如果定义一个java类时没有使用extends关键字声明其父类,则其父类为Object类。Object类定义了“对象”的基本行为,被子类默认继承。Object类中常用的方法equals方法Object类中默认equals方法的作用和逻辑运算符“==”相同,都是判断变量中存储的数据...

weixin_30014783的博客 253

c++ 学习 String类型

class std::string typedef basic_string string; String class 字符串是表示字符序列的对象。 标准字符串类提供了对此类对象的支持,其接口类似于标准的字节容器,但是添加了专门为使用单字节字符字符串进行操作而设计的特性。 string类是使用char(即,以其默认的char_traits和分配器类型作为其字符类型(有关模板的更多信息,请参阅ba...

xiabenshu的博客 199

Java 中 String、StringBuffer 和 StringBuilder 的区别是什么

String:不可变,适合少量字符串操作。:可变且线程安全,适合多线程环境中的频繁字符串修改。:可变且非线程安全,适合单线程环境中的高性能字符串处理。

yousuotu的博客 365

十 一:常用类

用于Java的学习

ALL BE WELL的博客 166

从零开始学Java,学习笔记Day12

包装类 – 注意:Integer底层,String的使用,StringBuffer和StringBuilder的使用,深入String,深入StringBuffer和StringBuilder。

qq_51876888的博客 444

6.6-6.8

本文介绍了Java中的日期时间处理和包装类相关内容。日期时间部分通过三个示例演示了DateFormat和SimpleDateFormat类的使用,包括不同格式的日期显示、自定义格式模板以及字符串到日期的解析。包装类部分通过IntegerDemo2展示了Integer类的缓存机制,说明valueOf()方法在-128到127范围内会复用缓存对象,而new操作符始终创建新对象。最后通过对比表格总结了String、StringBuffer和StringBuilder在可变性、线程安全性和性能上的核心区别,为选择合

2503_93783260的博客 323
上一篇: 获取Linux内核线程ID
下一篇: 通过指针访问虚函数表调用函数
山有木兮啊
博客等级 码龄8年 135粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值