一些坑
在java使用过程中碰到或者提前避坑,给自己提个醒,能少一些抓耳挠腮,多一些更深度的思考
1. for循环遍历对象的–>循环体操作List
我们这里新建一个测试的User类,属性:name,id,score,还有set,get方法,重写一下toString方法user={name=xxx,id=000,score=0.0},
- 初始化对象List
public static List<User> objectInit(){
List<User> userList=new ArrayList<>(List.of(
new User("alpha","1",98.8),
new User("alpha","2",88.8),
new User("beta","3",78.8),
new User("gamma","4",68.8)
));
return userList;
}
- 错误写法
删除元素以后,元素下标发生前移,但是指针是不变的,在处理下一个的时候随后的元素如果跟上一个元素相等的话,那么该元素就很容易被遗漏,在业务代码中不会报错,但是结果就不对
/** 使用for循环的错误写法
* */
for(int i=0;i<userList.size();i++){
if("alpha".equals(userList.get(i).getName())){
userList.remove(i);
}
}
/** 使用for循环的错误写法
* */
for(User user:userList){
if("alpha".equals(user.getName())){
userList.remove(user);
}
}
这里也是会报错,forEach是通过构造一个迭代器来实现的,如果移除这个元素,就会出现hashNext()/next()找不到
- 正确写法
- 十分的推荐使用stream来进行处理,简单高效,
/**直接使用stream流
*/
List<User> filteredList=userList.stream().filter(ele->!"alpha".equals(ele.getName())).collect(Collectors.toList());
或者利用迭代器来操作,也是调用iterator的remove,add方法,而非集合类的remove 跟add方法。
Iterator<User> iterator=userList.iterator();
while (iterator.hasNext()){
User element=iterator.next();
if("alpha".equals(element.getName())){
iterator.remove();
}
}
**2.值传递还是引用传递 **
这里涉及到Java是值传递还是参数传递,之前为了便于理解,很多人还有很多语言分两个(python)有值传递与引用传递两个概念,但是在Java里归根到底只有值传递,不存在引用传递,所谓的引用传递其实也是把内存地址传过去,其实还是值传递,。
- 修改对象属性
(其实我觉得这个例子并不是特别的好),但是能看清一些
public static void userListInit() {
User alphaUser=new User("alpha","001",98.0);
System.out.println("alphaUser:"+alphaUser);
/** 这里就是把alphaUser的内存地址传过去,然后changeUser()
*新建了一个对象,然后把对象的内存的指针指向了user,所以原内存地址上的数据没有发生任何改变
*/
changeUser(alphaUser);
System.out.println("alphaUser:"+alphaUser);
/** 这里就是把alphaUser的内存地址传过去,然后changScore()传递的是内存地址
所以在原的内存地址上进行修改,alphaUser的score为100.0
*/
changeScore(alphaUser);
System.out.println(alphaUser);
}
public static void changeUser(User user){
user=new User("Test","xxx",0.0);
System.out.println(user);
}
public static void changeScore(User user){
user.setScore(100.0);
System.out.println(user);
}
3.计算过程中的数值类型的隐式转换
/**
这个函数运算的出来三个不同的结果,
1、第一个肯定是超过了int类型的范围,所以被截断,结果是854421678
2、第二个前两个int类型进行计算,得到的结果也是int类型,那么也是超过了int类型的范围,也是会被截断
3、第三个因为第一是long类型,一个是int类型,那么得到的类型是long类型,所以第三个才是正确的结果。
所以一些大数字进行运算时,要注意隐式转换以及类型的范围。
*/
public static void alphaFunc(){
System.out.println(999999999*999999999*2222);
System.out.println(999999999*999999999*2222L);
System.out.println(999999999L*999999999*2222);
}
4.IO资源的释放
public static void alphaFunc(File[] files){
InputStream inputStream=null;
try {
for(File file:files){
inputStream=new FileInputStream(file);
}
}catch (Exception e){
// do something
}finally {
if(inputStream==null){
try{
inputStream.close();
}catch (IOException e){
// do somethings
}
}
}
}