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

标签: java 小技巧 基础
9人阅读 评论(0) 收藏 举报
分类:

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

1.Java +=操作符实质

看了这个是不是觉得这有啥难的,不就是一个加法吗?但还真不是这么简单。

可以试试在编辑器中输入以下代码

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库我就不说了,因为我也没用过,我们就看看自己写一个函数怎么搞。

/**
 * 将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() : ""; 
}

写个主函数测试一下

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() 方法,所以它是固定大小的。

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

Collections.addAll(arraylist, array);

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

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的键和值时,就可以使用这个方法

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

for(Integer i:map.keySet()) { 
    System.out.println(i); 
} 
for(String s:map.values()) { 
    System.out.println(s); 
}

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

方法三:使用Iterator迭代

使用泛型

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(低效率,好吧,我就是一直用的这种低效率的方法)

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???这么简单,不就是一个循环遍历吗??

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

String[] values = {"A", "B", "C", "D"};
if(Arrays.asList(values).contains("A")) { 
    System.out.println("6666"); 
} else { 
    System.out.println("5555"); 
}

自己写逻辑

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

for(String s:values) { 
    if(s.equals("A")) { 
        return true; 
    } else { 
        return false; 
    } 
}

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

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,如下

public static boolean useList(String[] arr, String targetValue) {     
    return Arrays.asList(arr).contains(targetValue); 
}
for(String s:values) { 
    if(s.equals("A")) { 
        return true; 
    } else { 
        return false; 
    } 
}

好了,今天先写5个问题,去吃饭了。越写越有意思,本渣渣表示很惊奇啊,欲知后事如何,请看明天的博文。

查看评论

跟着王进老师学开发之Java篇第一季:基础语法篇

-
  • 1970年01月01日 08:00

30个java编程小技巧

Java是目前最流行的编程语言之一——它可以用来编写Windows程序或者是Web应用,移动应用,网络程序,消费电子产品,机顶盒设备,它无处不在。 有超过30亿的设备是运行在Java之上的。根据...
  • my_name_nb
  • my_name_nb
  • 2017-03-28 21:33:45
  • 1818

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

上了一天的课,等下18:30还得上课,趁这个时间先更新一波。 6.如何从一个多层嵌套循环中直接跳出? for (Type type : types) { for (Type...
  • a_helloword
  • a_helloword
  • 2018-04-17 21:24:17
  • 7

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

16.wait()和sleep()的区别? 问题: 在线程里 wait() 和 sleep() 的区别? 我的理解是执行 wait() 语句后,该线程仍是运行态,并且会占用CPU,但是执行 sl...
  • a_helloword
  • a_helloword
  • 2018-04-20 08:34:23
  • 9

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

继续昨天的话题,越看到后面越吃力啊,感觉都理解一点,但却只是停留在表面,唉,虽然每篇文章只更新五个问题,但却要花我几个小时。坚持吧,坚持把每个问题都深入一点,自己也会收获更多。 11.Has...
  • a_helloword
  • a_helloword
  • 2018-04-18 21:32:59
  • 7

eclipse一些实用小技巧

IDE是我们最常用的工具之一。熟练运用好工具,能很大程度提到生产率。为此,本博主特意将一些遇到的实用的能极大提高生产率的小技巧记录如下。后续会不断补充更新。1.高亮匹配大括号对于c++代码或者java...
  • bitcarmanlee
  • bitcarmanlee
  • 2016-07-09 19:48:06
  • 974

java开发中的一些常用小技巧

  • 2012年02月17日 16:41
  • 34KB
  • 下载

java 中的小技巧

1.可变参数 2.静态导包 1.可变参数 System.out.println(add(1,2,3,4,5,6)); public static int add(int...
  • zhangyitian5
  • zhangyitian5
  • 2017-01-04 20:53:18
  • 103

java基础之基本语法

JAVA的基本语法 一、程序框架 publicclassHelloWorld { publicstaticvoidmain(String[] args) ...
  • guochan_xl
  • guochan_xl
  • 2015-07-04 11:47:50
  • 1247

java的一些小技巧!

在这个世界不可能存在完美的东西,不管完美的思维有多么缜密,细心,我们都不可能考虑所有的因素,这就是所谓的智者千虑必有一失。同样的道理,计算机的世界也是不完美的,异常情况随时都会发生,我们所需要做的就是...
  • u012402926
  • u012402926
  • 2016-07-15 22:06:04
  • 382
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 9427
    积分: 391
    排名: 19万+
    博客专栏
    最新评论