杂项2

简介: 本文介绍了Java编程中的多个实用知识点,涵盖集合操作、循环控制、Map遍历、类型安全、多线程等内容。包括不可变列表、集合添加判断、死循环登录验证、Map键值对遍历方式、链式调用的潜在问题、泛型类型擦除处理、增强for循环应用、列表合并与去重方法、输入流读取机制、asList的使用特点以及多线程Callable和FutureTask的协作执行流程,适用于Java开发者提升编码技巧和理解底层机制。

1.h1.stream().toList() 返回的是一个不可变列表(h1是hashset)

2.集合提供的add方法,返回值是boolean类型,所以可以根据返回值类型判断,是否添加成功

3.一般判断用户登录的时候,用while(true)死循环,根据判断结果来终止死循环(可以用"break;"

或者"return;"来终止

4.map是根据键找值,而不是索引(不存在),所有fori循环map是无法使用的;要根据键去找值;或者调用entry方法,切记不可链式调用会容易丢失类型

下面三行均是使用快捷键生成的

示例:

第一行:Map<Integer,String> t=entry.getValue();

第二行:Set<Map.Entry<Integer, String>> s1 = t.entrySet();

  • 作用:先将 entry.getValue() 的结果赋值给变量 t,再调用 t.entrySet()。
  • 优势:
  • 显式声明 t 的类型,增强代码可读性。
  • 便于后续对 t 进行其他操作(如修改、复用)。

第三行: Set set = entry.getValue().entrySet(); (链式调用)

  • 问题:
  • 未指定泛型,set 的类型为 Set(原始类型),失去类型安全。
  • 无法直接获取 Map.Entry<Integer, String> 的类型信息,需要强制转换。

形式上第一行+第二行等价于第三行,区别主要在于 类型安全 和 代码可读性,本质上两者的功能是一致的。

5.如果不知道索引,可以用增强for循环(在嵌套中)

6.元素去重合并(两个list类型)

合并:使用stream提供的concat方法或者 l1,add(l2)

去重:(思想转换为set)使用工具类collect方法或者Set<String>s1=new HashSet<>(l3);

7.类型擦除

Set<String>s1 =new TreeSet<>((o1, o2) -> o1.compareTo(o2));

//虽然你显式创建了 TreeSet,但通过匿名 Comparator 赋值给 Set 接口变量时,
// 类型信息被擦除,导致编译器无法识别 TreeSet 的特有方法(如 first()、last())。
  1. 解决思路:
  • 方法一:将变量类型声明为 TreeSet,而非 Set。
  • 方法二:通过显式类型转换调用 last()。

8

针对for循环中嵌套if语句,但是不想else语句先执行,而是在for循环终结时在执行else,操作步骤

int a[]={1,2,3};
    for (int i = 0; i < a.length; i++) {
        if(3==a[i]){
            System.out.println(a[i]);
        }
        else
            System.out.println(1);
    }
}
int a[] = {1, 2, 3};
boolean hasThree = false;
for (int num : a) {
    if (num == 3) {
        hasThree = true;
        System.out.println(num);
    }
}
if (!hasThree) {
    System.out.println(1);  // 仅当数组中无3时执行
}

不使用else语句

针对输入流的read在流没有关闭的时候,调用一次,读取一次

对于指定读取长度的

byte[] byte1 =new byte[6];
in.read(byte1);

一次读取六个字节,in.read(byte1)本身就是6个字节,等价于等于的字节数组长度;含义是,读取6个字符,并把这6个字节存到字节数组中

read调用一次读取一次,如果调用后剩余的字符长度不足数组定义的长度,会进行覆盖,覆盖的是上一次读取的数组,而且是从头开始覆盖

示例

97 100 228 189 160 229 165 189
 a  d   你         好

第一次调用 read (byte1)

java

in.read(byte1); // 读取前6个字节


此时 byte1 数组内容为:


plaintext

[97, 100, 228, 189, 160, 229]
 a   d   你       ?


注意最后一个字节 229 是 "好" 字的第一个字节,单独无法构成完整字符。

第二次调用 read (byte1)

java

System.out.println(in.read(byte1)); // 剩余2个字节,返回2


此时方法会读取剩余的两个字节 [165, 189],并覆盖 byte1 数组的前两个位置:


java

byte1[0] = 165;  // 覆盖原有的 'a' (97)
byte1[1] = 189;  // 覆盖原有的 'd' (100)


但数组的后四个位置保持不变,因此最终 byte1 的内容为:


plaintext

[165, 189, 228, 189, 160, 229]
 ?    ?   你       ?


aslist特点

  • List<T> list = Arrays.asList(T... a)
  • 示例:java
List<String> list = Arrays.asList("apple", "banana", "cherry");
// 等价于:List<String> list = Arrays.asList(new String[]{"apple", "banana", "cherry"});


  • 特点:
  • 返回的 List 是固定大小的,不支持添加或删除元素(调用 add()、remove() 会抛出 UnsupportedOperationException)。

若需要可变大小的 List,可通过 new ArrayList<>(Arrays.asList(...)) 创建副本:

java

List<String> mutableList = new ArrayList<>(Arrays.asList("a", "b"));
mutableList.add("c");  // 正常添加元素

多线程理解:

//创建类l实现接口callable
//创建l的实例化对象
//创建futuretask的实例化对象,并将的l的对象传给futuretesk的构造器即是:FutureTask f1 =new FutureTask(c1);
//创建thread对象,后续步骤同上一步 Thread t1=new Thread(f1);
//thread.start线程启动

代码执行流程

  1. 主线程创建了 MyCallable 对象和 FutureTask 对象,并且启动了新线程。
  2. 新线程开始执行 FutureTask.run() 方法,该方法会调用 MyCallable.call() 方法。
  3. 主线程调用 futureTask.get() 方法后被阻塞,等待子线程计算结束。
  4. 子线程完成计算后,get() 方法返回结果,主线程继续执行后续操作。


  • 不要手动调用 call() 方法:要是手动调用了 call() 方法,就相当于在主线程里直接执行计算任务,这就失去了多线程并行执行的意义。
  • get() 方法的阻塞特性:get() 方法会使当前线程暂停执行,直到子线程完成任务。如果你希望主线程和子线程能够并发执行其他任务,可以在调用 get() 方法之前先执行一些操作。
  • 对于get阻塞特性的理解:一旦使用thread.start,则子线程就在和主线程并行的运行,在主线程运行到子线程的get方法时,如果子线程处理完成,会立即返回,否则会阻塞主线程;实质上,一旦子线程启动,子线程会在后台运行,主线程也在同时运行,只有主线程遇到get()时才会阻塞检查子线程是否运行结束
相关文章
|
9月前
|
Linux 虚拟化 iOS开发
UTM 5.0.1 发布 - 基于 QEMU 的 macOS 虚拟机与模拟器应用
UTM 5.0.1 发布 - 基于 QEMU 的 macOS 虚拟机与模拟器应用
934 2
UTM 5.0.1 发布 - 基于 QEMU 的 macOS 虚拟机与模拟器应用
|
人工智能
万相妙思+创意视频大赛开赛啦!双重赛道,奖励叠加!10万奖金池 + 新模型内测资格!
万相妙思+创意视频大赛开赛啦!双重赛道,奖励叠加!10万奖金池 + 新模型内测资格!
574 0
|
定位技术
基于vue3.5+vite7+element-plus网页聊天系统
最新版vite7.1+vue3.5+element-plus仿微信web网页版聊天vite7-webchat。
624 4
|
12月前
|
人工智能 Cloud Native 自然语言处理
拔俗AI智能体服务开发:你的7x24小时数字员工,让企业效率飙升的秘密武器
在“人效为王”时代,企业面临服务响应慢、成本高、协同难等痛点。阿里云AI智能体以自主决策、多模态交互、持续学习三大引擎,打造永不疲倦的“数字员工”,实现7×24小时高效服务,助力企业降本增效、驱动创新增长。(238字)
742 0
|
Java 测试技术 应用服务中间件
使用 Spring Boot 构建应用程序
本指南提供了 Spring Boot 如何帮助您加速应用程序开发的示例。
|
人工智能 监控 数据可视化
低代码开发平台,快速搭建云MES系统
低代码平台是一种通过可视化操作减少手工编码的高效开发工具,适用于快速构建和交付应用软件。万界星空科技的AI低代码云MES系统具备快速开发、灵活可扩展、降低维护成本、智能分析与决策等优势,支持生产计划、质检、库存管理、数据大屏、自定义报表等功能,助力企业实现生产过程的数字化和智能化转型,提升运营效率和市场竞争力。
1042 4
|
安全 虚拟化 数据中心
VMware
VMware
896 3
|
人工智能 搜索推荐
强大的AI搜索引擎——秘塔AI搜索
【2月更文挑战第17天】强大的AI搜索引擎——秘塔AI搜索
5746 2
强大的AI搜索引擎——秘塔AI搜索
|
Dart 前端开发 Android开发
【Flutter前端技术开发专栏】Flutter中的平台特定代码实现
【4月更文挑战第30天】Flutter旨在实现跨平台移动应用开发,但有时需针对iOS或Android编写特定代码。平台通道是关键机制,允许Dart代码与原生代码交互。通过`MethodChannel`等实现跨平台通信,然后在iOS和Android上响应调用。条件编译则在编译时决定特定平台代码。本文展示了如何在Flutter中处理平台特定功能,包括示例代码和总结。
832 0
【Flutter前端技术开发专栏】Flutter中的平台特定代码实现
DC电源模块和AC电源模块两种电源模块对比分析
DC电源模块和AC电源模块是两种常见的电源模块,它们有一些相似之处,也有一些不同之处。下面是它们之间的对比分析:
DC电源模块和AC电源模块两种电源模块对比分析