2024-08-27

在Java中,封装是一种将数据和行为组合在一起,并隐藏内部实现细节的机制。封装可以使得代码模块化,易于维护,同时提供了代码的安全性。

以下是一个使用封装的简单例子:




public class Person {
    // 私有属性,外部无法直接访问
    private String name;
    private int age;
 
    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    // 公有方法,用于设置和获取私有属性的值
    public void setName(String name) {
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public int getAge() {
        return age;
    }
}
 
public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 25);
        // 通过公有方法访问和修改私有属性
        person.setName("Bob");
        System.out.println("Name: " + person.getName());
        person.setAge(26);
        System.out.println("Age: " + person.getAge());
    }
}

在这个例子中,Person 类有两个私有属性 nameage,以及对应的公有方法 setNamegetNamesetAgegetAge,用于对这两个属性进行设置和获取。这样,外部代码只能通过这些公有方法与属性交互,而不能直接访问私有属性,从而保护了数据的安全性和完整性。

2024-08-27

题目描述:

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变字符相对顺序的情况下,从字符串中删除某些字符或者不删除的情况。

回文定义为:正读和反读都一样的字符串。

示例 1:

输入:s = "bbbab"

输出:4

解释:一个可能的最长回文子序列为 "bbbb" 。

示例 2:

输入:s = "cbbd"

输出:2

解释:一个可能的最长回文子序列为 "bb" 。

提示:

1 <= s.length <= 1000

s 只包含小写英文字母

解法:

动态规划,使用二维数组 dp 来记录子问题的解。其中 dp[i][j] 表示字符串 s 从 i 到 j 的子串的最长回文子序列的长度。

状态转移方程为:

  • 如果 s[i] == s[j] 且 i 和 j 的下标差值不大于 1(即 i 和 j 是相邻的),那么 dp[i][j] = dp[i+1][j-1] + 2。
  • 如果 s[i] != s[j] 或者 i 和 j 的下标差值大于 1,那么 dp[i][j] = max(dp[i+1][j], dp[i][j-1])。

初始化:

  • 对角线上的元素都初始化为 0,因为 dp[i][i] 总是 1(自身是回文子序列)。
  • 其他位置初始化为 max(0, j - i + 1 - 2),即 j - i + 1 和 0 中的较大值,这是因为如果 i 和 j 之间没有公共字符,那么最长回文子序列长度至少为 j - i + 1。

时间复杂度:O(n^2)




class Solution {
    public int longestPalindromeSubseq(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
 
        for (int i = 0; i < n; i++) {
            dp[i][i] = 1;
        }
 
        for (int len = 2; len <= n; len++) {
            for (int i = 0; i < n - len + 1; i++) {
                int j = i + len - 1;
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                } else {
                    dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
                }
            }
        }
 
        return dp[0][n - 1];
    }
}
2024-08-27

在Spring Boot中,你可以使用@EventListener注解来监听特定的事件,并处理它们。以下是一个简单的例子:

首先,定义一个事件类:




public class MyEvent {
    private String message;
 
    public MyEvent(String message) {
        this.message = message;
    }
 
    public String getMessage() {
        return message;
    }
}

然后,创建一个事件监听器:




import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
 
@Component
public class MyEventListener {
 
    @EventListener
    public void handleMyEvent(MyEvent event) {
        System.out.println("Event received: " + event.getMessage());
    }
}

最后,在某个地方发布这个事件:




import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
 
@Service
public class MyService {
 
    @Autowired
    private ApplicationEventPublisher publisher;
 
    public void doSomething() {
        // ... do something
        publisher.publishEvent(new MyEvent("Action performed"));
    }
}

当你调用doSomething()方法时,MyEvent事件被发布,MyEventListenerhandleMyEvent方法会被调用来处理这个事件。

2024-08-27

报错信息 "Exception in thread "main" java.lang.IllegalArgumentException: L" 表示在Java程序的主线程中发生了一个非法参数异常。这通常意味着方法接收到了一个不合法或不适当的参数。

解决这个问题通常需要以下步骤:

  1. 查看完整的异常堆栈跟踪信息,以确定异常发生的确切位置和方法调用。
  2. 检查引发异常的方法调用,确认传递给它的参数是否符合预期。
  3. 如果参数是用户输入或外部来源的,确保进行了适当的验证和格式化。
  4. 如果异常与资源加载或文件路径有关,确保资源路径正确并且资源可访问。

由于报错信息不完整,无法提供更具体的解决方案。如果有更多的错误信息或代码上下文,可以提供更详尽的帮助。

2024-08-27

由于篇幅限制,我将提供一个简单的Java多线程练习题的解决方案。该题目创建两个线程,这两个线程交替打印数字和字母。




public class ThreadExercise implements Runnable {
    private int count = 0;
    private boolean letter = true; // 控制交替打印数字和字母
 
    @Override
    public void run() {
        while (count < 10) {
            synchronized (this) {
                if (letter) {
                    System.out.println("Thread " + Thread.currentThread().getId() + ": " + (char)('A' + count) + " ");
                } else {
                    System.out.println("Thread " + Thread.currentThread().getId() + ": " + count + " ");
                }
                letter = !letter; // 切换打印状态
                count++;
                // 唤醒其他线程
                this.notifyAll();
                // 当count小于5时,当前线程等待
                if (count < 5) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
 
    public static void main(String[] args) {
        ThreadExercise exercise = new ThreadExercise();
        Thread t1 = new Thread(exercise);
        Thread t2 = new Thread(exercise);
        t1.start();
        t2.start();
    }
}

这段代码定义了一个ThreadExercise类,实现了Runnable接口。在run方法中,使用synchronized块来确保线程安全。通过notifyAllwait方法,实现了线程间的通信和合作。两个线程交替运行,打印出数字和字母,直到打印到9。

2024-08-27

@Data 是一个常用于 Lombok 库的注解,它是一个快速生成 getter/setter 方法,构造器,equals(),canEqual(),hashCode(),toString() 方法的工具。

使用 @Data 注解,你无需为你的类手写大量的模板代码。相反,你只需要使用一个注解,Lombok 就会自动为你生成所有的“数据”类方法。

这是一个简单的使用 @Data 的例子:




import lombok.Data;
 
@Data
public class Example {
    private int number;
    private String text;
}

在这个例子中,@Data 注解会自动为 Example 类生成以下方法:

  • 默认的构造器
  • getter 方法:int getNumber()String getText()
  • setter 方法:void setNumber(int number)void setText(String text)
  • equals(Object) 方法
  • hashCode() 方法
  • toString() 方法,默认情况下会输出类名和所有属性

这些方法可以直接通过属性名被调用,无需手动编写。这在需要频繁使用 Java Beans 的应用中可以节省大量时间。

2024-08-27



import android.app.Application
import com.yanzhenjie.andserver.AndServer
import com.yanzhenjie.andserver.server.Server
 
class MyApplication : Application() {
 
    private lateinit var server: Server
 
    override fun onCreate() {
        super.onCreate()
 
        // 创建服务器对象,使用8080端口。
        server = AndServer.serverBuilder()
            .inetAddress("localhost") // 或者使用0.0.0.0监听所有地址
            .port(8080)
            .timeout(10, TimeUnit.SECONDS) // 设置服务器超时时间
            .filter(ServerLogFilter) // 添加日志过滤器
            .build()
 
        // 启动服务器。
        server.startup()
 
        // 停止服务器。
        // server.shutdown()
    }
}

这段代码展示了如何在Android应用程序中使用AndServer库来创建和启动一个简单的HTTP服务器。首先,我们创建了一个自定义的Application类,在其onCreate方法中初始化服务器设置,包括设置监听地址和端口,并配置了超时和日志过滤器。最后,我们启动服务器并在需要的时候可以关闭服务器。这是在Android平台上搭建HTTP服务器的一个简单例子。

2024-08-27

下面是一个简单的Java控制台应用程序,用于实现图书管理系统的部分功能。这个例子包括添加图书、列出图书列表以及搜索图书。




import java.util.ArrayList;
import java.util.Scanner;
 
public class BookManager {
    private ArrayList<Book> bookList;
 
    public BookManager() {
        bookList = new ArrayList<>();
    }
 
    public void addBook(Book book) {
        bookList.add(book);
        System.out.println("Book added successfully.");
    }
 
    public void listBooks() {
        if (bookList.isEmpty()) {
            System.out.println("No books available.");
            return;
        }
        for (Book book : bookList) {
            System.out.println(book);
        }
    }
 
    public Book searchBook(String title) {
        for (Book book : bookList) {
            if (book.getTitle().equals(title)) {
                return book;
            }
        }
        return null;
    }
 
    public static void main(String[] args) {
        BookManager bookManager = new BookManager();
        Scanner scanner = new Scanner(System.in);
 
        // 添加图书
        System.out.println("Enter book details:");
        System.out.println("Title: ");
        String title = scanner.nextLine();
        System.out.println("Author: ");
        String author = scanner.nextLine();
        Book newBook = new Book(title, author);
        bookManager.addBook(newBook);
 
        // 列出所有图书
        System.out.println("\nList of books:");
        bookManager.listBooks();
 
        // 搜索图书
        System.out.println("\nEnter title to search: ");
        String searchTitle = scanner.nextLine();
        Book foundBook = bookManager.searchBook(searchTitle);
        if (foundBook != null) {
            System.out.println("Found book: " + foundBook);
        } else {
            System.out.println("Book not found.");
        }
 
        scanner.close();
    }
}
 
class Book {
    private String title;
    private String author;
 
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }
 
    public String getTitle() {
        return title;
    }
 
    public String getAuthor() {
        return author;
    }
 
    @Override
    public String toString() {
        return "Book{" +
                "title='" + title + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}

这段代码定义了一个简单的Book类,以及一个BookManager类,它管理着一本书的列表。BookManager有添加图书、列出图书和搜索图书的功能。在main方法中,我们创建了BookManager

2024-08-27

在Java中,要实现导出的Excel内容自动换行,可以使用Apache POI库。以下是一个简单的例子,演示如何使用Apache POI创建一个Excel文件,并设置单元格样式使得内容自动换行。

首先,确保你的项目中包含了Apache POI的依赖。

Maven依赖如下:




<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>

然后,使用以下Java代码创建一个简单的Excel文件,并设置单元格内容自动换行:




import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
public class AutoWrapTextExample {
    public static void main(String[] args) throws IOException {
        Workbook workbook = new XSSFWorkbook(); // 创建工作簿
        Sheet sheet = workbook.createSheet("Sheet1"); // 创建工作表
 
        Row row = sheet.createRow(0); // 创建一行
        Cell cell = row.createCell(0); // 创建单元格
 
        cell.setCellValue("这是一段需要自动换行的文本内容,这段文本很长,需要在Excel中自动换行显示。"); // 设置单元格内容
 
        CellStyle style = workbook.createCellStyle(); // 创建单元格样式
        style.setWrapText(true); // 设置自动换行
        cell.setCellStyle(style); // 应用单元格样式
 
        // 写入到文件
        try (FileOutputStream outputStream = new FileOutputStream("autowrap.xlsx")) {
            workbook.write(outputStream);
        }
 
        workbook.close(); // 关闭工作簿资源
    }
}

运行上述代码,将创建一个名为autowrap.xlsx的Excel文件,其中的A1单元格内容将自动换行显示。

2024-08-27

在Java中,要解析PDF和Word文档以获取其中的表格和文本内容,可以使用Apache PDFBox和Apache POI库。以下是使用这两个库的示例代码。

解析PDF文件中的表格和文本内容:




import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripperByArea;
import org.apache.pdfbox.text.TextPosition;
 
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;
import java.util.List;
 
public class PDFParser {
    public static void main(String[] args) throws IOException {
        try (PDDocument document = PDDocument.load(new File("example.pdf"))) {
            PDFTextStripperByArea stripper = new PDFTextStripperByArea() {
                @Override
                protected void writeString(String str, List<TextPosition> textPositions) {
                    for (TextPosition position : textPositions) {
                        String unicode = position.getUnicode();
                        if (unicode != null) {
                            Rectangle2D.Float bounds = position.getBounds();
                            // 检查bounds是否接近表格边界
                            // 根据bounds做逻辑处理
                        }
                    }
                }
            };
            stripper.addRegion("tableArea", new Rectangle2D.Double(100, 100, 400, 300)); // 假设表格在页面的(100,100)位置,宽400,高300
            stripper.extractRegions(document);
            String text = stripper.getTextForRegion("tableArea");
            System.out.println(text);
        }
    }
}

解析WORD文件中的表格和文本内容:




import org.apache.poi.xwpf.usermodel.*;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
 
public class WordParser {
    public static void main(String[] args) throws IOException {
        try (FileInputStream fis = new FileInputStream(new File("example.docx"));
             XWPFDocument document = new XWPFDocument(fis)) {
            for (IBodyElement element : document.getBodyElements()) {
                if (element instanceof XWPFParagraph) {
                    XWPFParagraph paragraph = (XWPFParagraph) element;
                    String text = paragraph.getText();
                    // 处理文本内容
                } else if (element instanceof XWPFTable) {
                    XWPFTable table = (XWPFTable) element;