2024-08-26



public class Main {
    public static void main(String[] args) {
        // 创建String对象
        String str1 = "Hello, World!";
        String str2 = new String("Hello, World!");
 
        // 输出字符串
        System.out.println(str1);
        System.out.println(str2);
 
        // 比较字符串内容是否相等
        System.out.println("str1 == str2: " + str1.equals(str2));
 
        // 获取字符串长度
        System.out.println("Length of str1: " + str1.length());
 
        // 获取特定位置的字符
        char charAt = str1.charAt(6);
        System.out.println("Character at index 6: " + charAt);
 
        // 查找字符或字符串在另一字符串中的位置
        int index = str1.indexOf('W');
        System.out.println("Index of 'W': " + index);
 
        // 拼接字符串
        String str3 = " Welcome to Java!";
        String concatenated = str2.concat(str3);
        System.out.println("Concatenated string: " + concatenated);
 
        // 替换字符串中的字符或子串
        String replaced = str1.replace('World', 'Java');
        System.out.println("Replaced string: " + replaced);
 
        // 分割字符串
        String[] parts = str1.split(",");
        for (String part : parts) {
            System.out.println("Part of the string: " + part);
        }
 
        // 转换为小写或大写
        String lowerCase = str1.toLowerCase();
        String upperCase = str1.toUpperCase();
        System.out.println("Lower case string: " + lowerCase);
        System.out.println("Upper case string: " + upperCase);
 
        // 去除字符串首尾的空白字符
        String trimmed = str1.trim();
        System.out.println("Trimmed string: " + trimmed);
    }
}

这段代码展示了如何在Java中使用String类的常用方法,包括创建字符串对象、字符串比较、获取长度、获取特定位置的字符、查找字符或子串的位置、字符串的拼接、替换、分割、转换大小写以及去除首尾空白。这些操作是学习任何编程语言时的基础,对于理解字符串处理在编程中的应用至关重要。

2024-08-26



<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 定义日志的根级别和输出方式 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>
        </encoder>
    </appender>
 
    <!-- 每天滚动生成日志文件,保留30天的日志 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/myapp.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天滚动生成日志文件,保留30天的日志 -->
            <fileNamePattern>logs/myapp.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
    </appender>
 
    <!-- 设置具体包或类的日志级别和使用的appender -->
    <logger name="com.example.myapp" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </logger>
 
    <!-- 日志根级别设置 -->
    <root level="ERROR">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

这个配置文件定义了两个主要的appender:STDOUT和FILE。STDOUT用于在控制台输出日志,FILE用于将日志滚动保存到文件中。对于具体的日志记录器(logger),我们设置了com.example.myapp包下的日志级别为DEBUG,并且指定了两个appender。这确保了对该包进行日志记录时会同时在控制台和文件中记录DEBUG及以上级别的日志。此外,根级别(root level)被设置为ERROR,这意味着只有错误级别以上的日志会被记录,这在生产环境中可以帮助节省磁盘空间并提高性能。

2024-08-26

在Java中,可以使用Apache PDFBox库将图片转换为PDF。以下是一个简单的例子,演示如何实现这一功能:

首先,确保你的项目中包含了PDFBox依赖。如果你使用Maven,可以添加以下依赖到你的pom.xml文件中:




<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.24</version>
</dependency>

然后,使用以下Java代码将图片转换为PDF:




import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 
import java.io.File;
import java.io.IOException;
 
public class ImageToPDF {
    public static void main(String[] args) {
        String imagePath = "path/to/image.jpg"; // 图片路径
        String pdfPath = "path/to/output.pdf"; // PDF输出路径
 
        try (PDDocument document = new PDDocument()) {
            PDPage page = new PDPage();
            document.addPage(page);
            PDImageXObject pdImage = PDImageXObject.createFromFile(imagePath, document);
            PDPageContentStream contentStream = new PDPageContentStream(document, page);
            contentStream.drawImage(pdImage, 0, 0, pdImage.getWidth(), pdImage.getHeight());
            contentStream.close();
 
            document.save(pdfPath);
            document.close();
            System.out.println("PDF created with image.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

确保替换imagePathpdfPath变量为你的图片和PDF文件的实际路径。这段代码会创建一个PDF文档,并将指定的图片插入到第一页。图片会被缩放以适应整个页面。

2024-08-26

try-with-resources 是 Java 7 引入的一个新特性,它允许在一个 try 块中声明一种或多种资源,在 try 块结束时自动关闭这些资源。资源是指在程序完成后必须关闭的对象,例如文件、数据库连接等。

使用 try-with-resources 的语法如下:




try (Resource res = createResource()) {
    // 使用资源 res
} catch (Exception e) {
    // 处理异常
}

其中 Resource 是一个实现了 java.lang.AutoCloseable 接口的资源类,createResource() 是返回资源对象的方法。

以下是一个简单的使用 try-with-resources 的例子:




import java.io.*;
 
public class TryWithResourcesExample {
    public static void main(String[] args) {
        try (FileReader fr = new FileReader("example.txt");
             BufferedReader br = new BufferedReader(fr)) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,FileReaderBufferedReader 对象都会在 try 块结束后自动关闭,即使发生异常也是如此。这样可以避免在 finally 块中手动关闭资源,从而减少代码量并提高程序的可靠性。

2024-08-26



public class TypeConversion {
    public static void main(String[] args) {
        // 自动类型转换(隐式)
        int i = 123;
        double d1 = i; // int类型自动转换为double类型
        System.out.println("d1 = " + d1);
 
        // 强制类型转换(显式)
        double d2 = 456.789;
        int i2 = (int) d2; // double类型转换为int类型,可能会丢失小数部分或者数值
        System.out.println("i2 = " + i2);
 
        // 基本类型包装类转换
        Integer integer = new Integer(123);
        int primitiveInt = integer.intValue(); // 包装类转基本类型
        System.out.println("primitiveInt = " + primitiveInt);
 
        // 字符串与基本类型的转换
        String stringInt = "123";
        int intFromString = Integer.parseInt(stringInt); // 字符串转基本类型
        System.out.println("intFromString = " + intFromString);
 
        String stringDouble = "456.789";
        double doubleFromString = Double.parseDouble(stringDouble); // 字符串转基本类型
        System.out.println("doubleFromString = " + doubleFromString);
 
        // 基本类型转字符串
        int intToConvert = 123;
        String stringFromInt = String.valueOf(intToConvert); // 基本类型转字符串
        System.out.println("stringFromInt = " + stringFromInt);
 
        double doubleToConvert = 456.789;
        String stringFromDouble = Double.toString(doubleToConvert); // 基本类型转字符串
        System.out.println("stringFromDouble = " + stringFromDouble);
    }
}

这段代码展示了Java中基本类型之间的转换,包括自动类型转换(隐式)、强制类型转换(显式),以及基本类型和字符串之间的转换。同时,它也展示了如何使用包装类IntegerDouble来进行转换和处理。这些是学习Java语言时需要深入理解的基础知识点。

2024-08-26

在Java中为PDF文件添加电子签章(关键字盖章),可以使用开源库iText。以下是一个简单的示例代码,演示如何使用iText 7为PDF文件添加关键字盖章。

首先,确保你的项目中包含了iText 7的依赖。如果你使用Maven,可以添加以下依赖:




<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.1.15</version>
    <type>pom</type>
</dependency>

以下是使用iText 7为PDF文件添加电子签章的示例代码:




import com.itextpdf.kernel.pdf.*;
import com.itextpdf.signatures.PdfSignatureAppearance;
import com.itextpdf.signatures.PrivateKeySignature;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
 
public class KeySignature {
    public static void main(String[] args) {
        String src = "src/main/resources/test.pdf"; // 原始PDF文件路径
        String dest = "src/main/resources/signed_test.pdf"; // 签名后的PDF文件路径
        String keystorePath = "src/main/resources/keystore.jks"; // 密钥库路径
        String alias = "test"; // 密钥别名
        String password = "password"; // 密钥库密码
 
        try {
            PdfReader reader = new PdfReader(src);
            FileOutputStream fos = new FileOutputStream(dest);
            PdfSigner signer = new PdfSigner(reader, fos, new StampingProperties());
            PrivateKey privateKey = KeyStoreUtil.getPrivateKey(keystorePath, alias, password);
 
            signer.setFieldName("SignatureField"); // PDF中的签名字段名称
            PdfSignatureAppearance appearance = signer.getSignatureAppearance();
            appearance.setReason("Reason");
            appearance.setLocation("Location");
            appearance.setContact("ContactInfo");
 
            IExternalSignature pks = new PrivateKeySignature(privateKey, "SHA256");
            signer.signDetached(pks);
 
            System.out.println("Signature applied successfully.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们假设有一个名为test.pdf的PDF文件,我们想要对它进行电子签名。我们使用了一个密钥库(keystore.jks),其中包含用于签名的私钥。代码中的KeyStoreUtil.getPrivateKey方法用于从密钥库中获取私钥。

请注意,这只是一个简化的示例,实际使用时你需要根据自己的密钥库和签名需求进行相应的调整。此外,你需要确保你有合适的权限来访问密钥库文件,并且已经在你的Java环境中正确安装了必要的安全证书。

2024-08-26



public class Main {
    public static void main(String[] args) {
        // 定义一个整型变量并初始化为100
        int myNumber = 100;
 
        // 打印变量的值
        System.out.println("整型变量myNumber的值为:" + myNumber);
 
        // 修改变量的值为200
        myNumber = 200;
 
        // 打印修改后的变量值
        System.out.println("修改后的整型变量myNumber的值为:" + myNumber);
    }
}

这段代码首先定义了一个整型变量myNumber,并将其初始化为字面常量100。然后,使用System.out.println()打印了该变量的值。接着,将变量myNumber的值修改为200,并再次打印以展示修改后的值。这个过程展示了如何声明变量、初始化变量、修改变量的值以及如何输出变量的值。

2024-08-26

在Java NIO中,DirectByteBuffer是一个特殊的缓冲区,它使用Java虚拟机(JVM)外部的直接内存区域。这种缓冲区可以提高I/O操作的性能,因为它减少了在Java堆内存和native I/O之间复制数据的需要。

直接内存通常不受Java堆大小的限制,这使得在大型数据集的传输过程中能够提供更好的性能。

创建一个DirectByteBuffer对象可以通过ByteBuffer.allocateDirect(int capacity)方法实现。

下面是一个简单的例子,展示了如何创建和使用DirectByteBuffer




import java.nio.ByteBuffer;
 
public class DirectByteBufferExample {
    public static void main(String[] args) {
        // 分配直接内存
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
 
        // 使用直接内存进行数据操作
        directBuffer.put((byte)1);
        directBuffer.put((byte)2);
        directBuffer.flip(); // 切换到读模式
 
        // 读取数据
        byte b1 = directBuffer.get();
        byte b2 = directBuffer.get();
 
        System.out.println("Read bytes: " + b1 + ", " + b2);
 
        // 释放直接内存
        directBuffer.clear();
        // 确保释放直接内存
        System.gc(); // 可以通过调用System.gc()来建议JVM进行垃圾回收,但这不保证会立即发生
    }
}

在实际应用中,直接内存的分配和释放可能会有一些特殊的考虑,因为它不是由JVM管理的,所以需要显式地管理其生命周期。当不再需要直接内存时,应该手动清除并释放它,以避免内存泄漏。在上述代码中,调用System.gc()是一个良好的习惯,但它不能保证垃圾回收器会立即执行,因此最好配合其他方法或者工具来确保直接内存被适当地释放。

2024-08-26

解释:

java.net.SocketException: Connection reset 这个错误通常表示当前的网络连接被对端(远程服务器或者服务)强制关闭了。原因可能是对端服务器崩溃、对端服务器主动关闭了连接、网络问题导致连接中断,或者是TCP协议的正常保活机制检测到对端已无响应。

解决方法:

  1. 检查网络连接是否稳定,排除网络问题。
  2. 确认远程服务器或服务是否运行正常,如果有访问控制列表(ACLs)或防火墙,确保你的IP地址或IP段没有被封禁。
  3. 如果是因为服务器的原因导致连接关闭,尝试重新连接。
  4. 增加应用程序的错误处理逻辑,捕获SocketException,并在合适的时候重试连接。
  5. 如果是长连接,可以实现心跳机制,定期发送数据包以保持连接活跃。
  6. 检查服务器端的日志,查看是否有更详细的错误信息,以便进一步诊断问题。
  7. 如果问题持续存在,可能需要联系远程服务器的管理员或者网络管理员进一步分析问题。
2024-08-26



public class BinarySearch {
 
    public static int binarySearch(int[] arr, int target) {
        int left = 0;
        int right = arr.length - 1; // 定义右边界
 
        while (left <= right) { // 当左边界小于等于右边界时执行循环
            int mid = left + (right - left) / 2; // 计算中间索引,防止溢出
 
            if (arr[mid] == target) { // 如果中间值等于目标值
                return mid; // 返回中间索引
            } else if (arr[mid] < target) { // 如果中间值小于目标值
                left = mid + 1; // 将左边界设置为中间索引的下一个位置
            } else { // 如果中间值大于目标值
                right = mid - 1; // 将右边界设置为中间索引的前一个位置
            }
        }
        return -1; // 如果没有找到目标值,返回-1
    }
 
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};
        int target = 7;
        int index = binarySearch(arr, target);
        if (index != -1) {
            System.out.println("找到目标值,索引为:" + index);
        } else {
            System.out.println("未找到目标值");
        }
    }
}

这段代码实现了二分查找算法,在一个有序数组中查找特定的元素,并返回其索引。如果找不到,则返回-1。这是一个常用的算法,对于学习数据结构和算法有重要的意义。