[Tips]Java&&Android Tips

来源:互联网 发布:jmeter数据库压力测试 编辑:程序博客网 时间:2024/06/11 01:56

1、Collection和Collections

Collection是接口,所有Java集合类(除实现Map接口的类)都实现了Collection接口。它定义了实现该接口的集合类中数据的操作和行为,所有直接或间接实现该接口的类都应该最少有两个构造函数:其中没有参数的一个用来构造一个空集合,另一个用来构造拥有不同集合类型但元素相同的集合。

Collections是类,包含了许多操作集合类的静态函数。

那么,如何将数组对象转化为List对象呢?可以使用以下代码:

Collections.addAll(arraylist, array);
另外附Java集合类关系图:(注意图中有一点错误:Map接口并没有继承Collection接口)

2、HashMap的遍历

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

1)使用For-Each迭代entries

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

Map<Integer, Integer> map = new HashMap<Integer, Integer>();for(Map.Entry<Integer, Integer> entry : map.entrySet()){    System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue())}
注意:For-Each循环是Java5新引入的,所以只能在Java5以上的版本中使用。如果你遍历的map是null的话,For-Each循环会抛出NullPointerException异常,所以在遍历之前你应该判断是否为空引用。

2)使用For-Each迭代keys和values

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

Map<Integer, Integer> map = new HashMap<Integer, Integer>();//iterating over keys onlyfor (Integer key : map.keySet()) {    System.out.println("Key = " + key);}//iterating over values onlyfor (Integer value : map.values()) {    System.out.println("Value = " + value);}
这个方法比entrySet迭代具有轻微的性能优势(大约快10%)并且代码更简洁。

3)使用Iterator迭代

使用泛型:

Map<Integer, Integer> map = new HashMap<Integer, Integer>();Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();while (entries.hasNext()) {    Map.Entry<Integer, Integer> entry = entries.next();    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());}

不适用泛型:

Map map = new HashMap();Iterator entries = map.entrySet().iterator();while (entries.hasNext()) {    Map.Entry entry = (Map.Entry) entries.next();    Integer key = (Integer)entry.getKey();    Integer value = (Integer)entry.getValue();    System.out.println("Key = " + key + ", Value = " + value);}
你可以使用同样的技术迭代keyset或者values。

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


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

3、如何判断数组中包含指定的值?

1)使用Arrays.asList(...).contains(...);

2)自己写查找逻辑:

a)对于无序数组:

public static boolean useLoop(String[] arr, String targetValue) {    for(String s: arr){        if(s.equals(targetValue))            return true;    }    return false;}
b)有序数组可以用二分查找(Arrays包含数组相关操作):

public static boolean useArraysBinarySearch(String[] arr, String targetValue) {     int a =  Arrays.binarySearch(arr, targetValue);    if(a >= 0)        return true;    else        return false;}
4、从多重循环中跳出(使用break+label)

public class Test {    public static void main(String[] args) {      outerloop:      for (int i=0; i < 5; i++) {        for (int j=0; j < 5; j++) {          if (i * j > 6) {            System.out.println("Breaking");            break outerloop;          }          System.out.println(i + " " + j);        }      }      System.out.println("Done");    }  }  
5、分割String字符串

使用String#split方法:

String string = "004-034556";String[] parts = string.split("-");String part1 = parts[0]; // 004String part2 = parts[1]; // 034556
需要注意的是,该方法的参数是个正则表达式,要注意对某些字符做转码。例如,.在正则表达式中表示任意字符,因此,如果你要通过.号做分割,需要这样写,split("\\.")或者split(Pattern.quote("."))。如果只是为了验证字符串中是否包含某个字符,使用String#contains方法就行。注意该方法的参数,不是正则表达式。

6、Java中对比String对象

  • 使用“==”:对应的是指针相等,也就是他们是否为同一个对象
  • 使用equals()方法:对应的是值相等,也就是逻辑相等

如果想比较String字符串内容是否相同,应该使用equals()方法。

/值是相等的new String("test").equals("test") // --> true // ... 值相等,但不是同个对象(指向不同的地址空间)new String("test") == "test" // --> false // ... 同上new String("test") == new String("test") // --> false // 这个返回true,是因为这种写法属于字符串字面量,编译器会维护一个常量池,相同的字面量,都会指向相同的一个对象"test" == "test" // --> true 
因此, 值的对比,一般都是用equals方法。字符串字面量之间的对比,也可以用==(大家知其所以然即可,但没必要用==)
下面多举个字符串字面量的例子,下面代码中,前四个对比,返回true,最后一个返回false。

public static final String test1 = "test";    public static final String test2 = "test";    @Test    public void test() {        String test3 = "test";        String test = "test";        System.out.println(test3.equals(test));        System.out.println(test3 == test);        System.out.println(test1.equals(test2));        System.out.println(test1 == test2);        System.out.println(test1 == new String("test"));    }
其他:

  • 如果你重写了equal方法,记得相对应地修改hashcode方法,否则将会违反这两个方法的对等关系,如果两个对象是相等(equal)的,那么两个对象调用hashCode必须产生相同的整数结果,即:equal为true,hashCode必须为true,equal为false,hashCode也必须为false。
  • 如果要忽略大小写进行对比,可以用equalsIgnoreCase()方法。
7、HashMap和HashTable的比较

  • Hashtable是同步的,加了synchronized锁,而HashMap不是。没有加synchronized锁的对象,性能通常比加了synchronized锁的对象要更好一些,因此,如果是非多线程程序,不需要考虑锁、同步等问题,那么使用HashMap更好。
  • Hashtable不允许空键和空值,而HashMap允许。
  • HashMap有个子类叫做LinkedHashMap,迭代时是有序的(按照插入时的顺序)。如果有需要,可以向上塑性转化为HashMap对象,而HashTable不行。
因此,如果考虑多线程可以使用HashTable,其余使用HashMap。

8、最近在研究音频编码格式时,看到许多关于数据大小的编码格式为:倒着写入的十六进制。可以使用以下方式将十六进制数据大小与十进制数据大小相互转换:

  • 倒置十六进制转十进制:

int len = ((0xff & header[0]) << 24 |(0xff & header[1]) << 16 | (0xff & header[2]) << 8 | (0xff & header[3]));

  • 十进制数据写入头文件(转为倒置十六进制):
int totalDataLen = 1024;header[4] = (byte) (totalDataLen & 0xff);header[5] = (byte) ((totalDataLen >> 8) & 0xff);header[6] = (byte) ((totalDataLen >> 16) & 0xff);header[7] = (byte) ((totalDataLen >> 24) & 0xff);



0 0
原创粉丝点击