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())。
- 解决思路:
- 方法一:将变量类型声明为
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线程启动
代码执行流程
- 主线程创建了
MyCallable
对象和FutureTask
对象,并且启动了新线程。 - 新线程开始执行
FutureTask.run()
方法,该方法会调用MyCallable.call()
方法。 - 主线程调用
futureTask.get()
方法后被阻塞,等待子线程计算结束。 - 子线程完成计算后,
get()
方法返回结果,主线程继续执行后续操作。
- 不要手动调用
call()
方法:要是手动调用了call()
方法,就相当于在主线程里直接执行计算任务,这就失去了多线程并行执行的意义。 get()
方法的阻塞特性:get()
方法会使当前线程暂停执行,直到子线程完成任务。如果你希望主线程和子线程能够并发执行其他任务,可以在调用get()
方法之前先执行一些操作。- 对于get阻塞特性的理解:一旦使用thread.start,则子线程就在和主线程并行的运行,在主线程运行到子线程的get方法时,如果子线程处理完成,会立即返回,否则会阻塞主线程;实质上,一旦子线程启动,子线程会在后台运行,主线程也在同时运行,只有主线程遇到get()时才会阻塞检查子线程是否运行结束