前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java编程的一些小技巧-----基础语法篇(1)

Java编程的一些小技巧-----基础语法篇(1)

作者头像
秃头哥编程
发布2019-06-04 17:37:41
5260
发布2019-06-04 17:37:41
举报
文章被收录于专栏:秃头哥编程秃头哥编程

今天在github上面看到了一个很好的项目,是在Stack Overflow上面点赞数top100的关于Java的回答,看了一些,感觉十分实用,对于新手来说,能加深对Java的认识,同时也能让代码更简洁。所以想写下这系列的博文,每个回答我都会亲自用代码检验一下,下面一起来看看这些小技巧吧,绝不会让你失望。

1.Java +=操作符实质

看了这个是不是觉得这有啥难的,不就是一个加法吗?但还真不是这么简单。可以试试在编辑器中输入以下代码

代码语言:javascript
复制

int a = 5;
double b = 10.5;
a = a + b; // 这行编译出错
a += b; // 这行没有问题
a = a + (int)b; //这行也没问题

是不是感觉有点惊讶?a = a + b;不能通过,a += b;怎么就能通过了呢?其实再看这个回答之前,我也一直以为a += b其实就等同于a = a + b;然后事实明显不是这样。那这是什么原因呢?看看官方文档的解释就知道了。

意思就是对于E1 op= E2这样的表达式来说,等同于(T)(E1 op E2)。op=诸如+=、-=、*=、/=这样的运算符,E1和E2表示两个操作数,T表示E1的数据类型。那么我们上面的代码中a += b;就变成了(int)(a + b);

2.将InputStream转化为String

使用apache库我就不说了,因为我也没用过,我们就看看自己写一个函数怎么搞。

代码语言:javascript
复制
/**
 * 将InputStream转化为String
 * @param is
 * @return
 */ 
static String convertStreamToString(InputStream is) { 
    @SuppressWarnings("resource") 
    // \A表示文件的开头 
    Scanner read = new Scanner(is).useDelimiter("\\A"); 
    return read.hasNext() ? read.next() : ""; 
}

写个主函数测试一下

代码语言:javascript
复制

FileInputStream fis = new FileInputStream("test.txt"); 
System.out.println(convertStreamToString(fis));

完全没毛病,大家可以自己试试。

3.将数组转化为List

相信有挺多人和我一样,要么用循环,遍历数组把数组的值一个一个赋值给List。。。这是最傻逼的方法。再者,就是使用Arrays.asList()方法。用这个方法的确没毛病,但却是有坑滴。

  • 这样生成的List是定长的,意味着你不能进行remove和add操作,不然会抛出UnsupportedOperationException。(好吧,难怪我说以前怎么用这个方法总报错,现在终于找到答案了)
  • 如果修改数组的值,则List中的值也会变。

之所以会出现这样的情况,是因为Arrays.asList()方法返回的是Arrays的内部静态类,而不是Java.util.ArrayList的类。这个java.util.Arrays.ArrayList有set(),get(),contains()方法,但是没有任何add() 方法,所以它是固定大小的。

如果你希望避免这两个坑,请使用下面的方式

代码语言:javascript
复制
Collections.addAll(arraylist, array);

新技能get。我们来看看代码

代码语言:javascript
复制

Integer[] a = new Integer[]{1, 2, 3}; 
List<Integer> r = new ArrayList<Integer>(); 
r = Arrays.asList(a); 
//Collections.addAll(r, a); 
//r.add("d"); 
//a[0] = 10;
System.out.println(r);

这里需要提醒的是,如果你是基本类型比如int类型的数组,也应该使用Integer来进行包装,不然会报错。

4.Map遍历

在Java中有多种遍历HashMap的方法。让我们回顾一下最常见的方法和它们各自的优缺点。由于所有的Map都实现了Map接口,所以接下来方法适用于所有Map(如:HaspMap,TreeMap,LinkedMap,HashTable,etc)

方法一:使用for-each迭代entries

这是最常见的方法,并在大多数情况下更可取的。当你在循环中需要使用Map的键和值时,就可以使用这个方法

代码语言:javascript
复制
for(Map.Entry<Integer, String> entry:map.entrySet()) { 
    Integer key = entry.getKey(); 
    String value = entry.getValue(); 
}

注意:For-Each循环是Java5新引入的,所以只能在Java5以上的版本中使用。如果你遍历的map是null的话,For-Each循环会抛出NullPointerException异常,所以在遍历之前你应该判断是否为空引用。

方法二:使用for-each迭代keys和values

如果你只需要用到map的keys或values时,你可以遍历KeySet或者values代替entrySet

代码语言:javascript
复制
for(Integer i:map.keySet()) { 
    System.out.println(i); 
} 
for(String s:map.values()) { 
    System.out.println(s); 
}

这个方法比entrySet迭代具有轻微的性能优势(大约快10%)并且代码更简洁

方法三:使用Iterator迭代

使用泛型

代码语言:javascript
复制
Iterator<Map.Entry<Integer, String>> entries = r.entrySet().iterator(); 
while(entries.hasNext()) { 
    Map.Entry<Integer, String> entry = entries.next(); 
    Integer key = entry.getKey(); 
    String value = entry.getValue(); 
    System.out.println(key + ":" + value); 
}

不使用泛型(算了,还是推荐大家使用泛型吧。。。)

你可以使用同样的技术迭代keyset或者values

这个似乎有点多余但它具有自己的优势。首先,它是遍历老java版本map的唯一方法。另外一个重要的特性是可以让你在迭代的时候从map中删除entries的(通过调用iterator.remover())唯一方法.如果你试图在For-Each迭代的时候删除entries,你将会得到unpredictable resultes 异常。

从性能方法看,这个方法等价于使用For-Each迭代

方法四:迭代keys并搜索values(低效率,好吧,我就是一直用的这种低效率的方法)

代码语言:javascript
复制

for (Integer key : map.keySet()) { 
    Integer value = map.get(key); 
    System.out.println("Key = " + key + ", Value = " + value); 
}

这个方法看上去比方法#1更简洁,但是实际上它更慢更低效,通过key得到value值更耗时(这个方法在所有实现map接口的map中比方法#1慢20%-200%)。如果你安装了FindBugs,它将检测并警告你这是一个低效的迭代。这个方法应该避免。

总结

如果你只需要使用key或者value使用方法#2,如果你坚持使用java的老版本(java 5 以前的版本)或者打算在迭代的时候移除entries,使用方法#3。其他情况请使用#1方法。避免使用#4方法。

5.如何测试一个数组中是否包含指定的值

excuse me???这么简单,不就是一个循环遍历吗??

简单而优雅的方法(好,这个技能掌握了)

代码语言:javascript
复制
String[] values = {"A", "B", "C", "D"};
if(Arrays.asList(values).contains("A")) { 
    System.out.println("6666"); 
} else { 
    System.out.println("5555"); 
}

自己写逻辑

问题的本质,其实是一个查找的问题,即查找一个数组是否包含某个值。对于原始类型,若是无序的数组,可以直接写一个 for 循环:

代码语言:javascript
复制
for(String s:values) { 
    if(s.equals("A")) { 
        return true; 
    } else { 
        return false; 
    } 
}

若是有序的数组,可以考虑二分查找或者其他查找算法:

代码语言:javascript
复制

public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
      int a =  Arrays.binarySearch(arr, targetValue);
      if(a >= 0)
         return true;
      else
         return false; 
}

若数组里包含的是一个个对象,实际上比较就是引用是否相等(String 类型是判断 值是否相等),本质就是比较 hashcode 和 equal 方法,可以考虑使用 List 或者 Set,如下

代码语言:javascript
复制

public static boolean useList(String[] arr, String targetValue) {     
    return Arrays.asList(arr).contains(targetValue); 
}

代码语言:javascript
复制
for(String s:values) { 
    if(s.equals("A")) { 
        return true; 
    } else { 
        return false; 
    } 
}

文章到这里就暂时先结束啦。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 秃头哥编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.Java +=操作符实质
  • 2.将InputStream转化为String
  • 5.如何测试一个数组中是否包含指定的值
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档