package demo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.junit.Test;
/**
* @author songhao
* @Description: TODO(Java程序员们最常犯的错误)
*/
public class DemoError {
/**
* @author songhao
* @Title: name
* @Description: TODO(将数组转化为list)
* @param 设定文件
* @return void 返回类型
* @throws @date
* 2017年12月11日 下午2:53:34
*/
@Test
public void first() {
String arr[] = new String[] { "1", "2", "3", "4", "5" };
List<String> list = Arrays.asList(arr);
try {
list.add("0");
} catch (Exception e) {
e.printStackTrace();
}
for (String string : list) {
System.out.println(string);
}
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
try {
arrayList.add("hehe");
} catch (Exception e) {
e.printStackTrace();
}
for (String string : arrayList) {
System.out.println(string);
}
}
/**
* @author songhao
* @Title: second
* @Description: TODO(在一个循环中删除一个列表中的元素)
* @param 设定文件
* @return void 返回类型
* @throws @date
* 2017年12月11日 下午3:21:01
*/
@Test
public void second() {
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
// 在这个方法中有一个严重的错误。当一个元素被删除时,列表的大小缩小并且下标变化,所以当你想要在一个循环中用下标删除多个元素的时候,它并不会正常的生效。
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
System.out.println(list);
// 你也许知道在循环中正确的删除多个元素的方法是使用迭代,并且你知道java中的foreach循环看起来像一个迭代器,但实际上并不是。考虑一下下面的代码:
// 它会抛出一个ConcurrentModificationException异常。
ArrayList<String> list1 = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
try {
// 这种增强for方法对于集合来说相当于使用了iterator,在进行add或者remove这样的对结构进行操作时候会进行检查
for (String s : list1) {
if (s.equals("a")) {
list1.remove(s);
}
}
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
System.out.println(list1);
/**
* 上面的增强for循环和这个是等价的 for (Iterator iterator = list1.iterator();
* iterator.hasNext();) { String string = (String) iterator.next(); }
*/
// for和while 都是循环 ,要是知道 循环次数 可以 用for,
// 要是不知道循环的次数,但是知道循环的终止条件 , 则用while.
ArrayList<String> list2 = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list2.iterator();
while (iter.hasNext()) {
String s = iter.next();
if (s.equals("a")) {
iter.remove();
}
}
System.out.println(list2);
}
@Test
public void third() {
// TODO Auto-generated method stub
class Dog {
String color;
Dog(String c) {
color = c;
}
public String toString() {
return color + " dog";
}
}
HashMap<Dog, Integer> hashMap = new HashMap<Dog, Integer>();
Dog d1 = new Dog("red");
Dog d2 = new Dog("black");
Dog d3 = new Dog("white");
Dog d4 = new Dog("white");
// 注意,我们错误的将”white dogs”添加了两次,但是HashMap却接受了两只”white dogs”。
// 这不合理(因为HashMap的键不应该重复),我们会搞不清楚真正有多少白色的狗存在。 五只呢?还是二十只
hashMap.put(d1, 10);
hashMap.put(d2, 15);
hashMap.put(d3, 5);
hashMap.put(d4, 20);
// print size
System.out.println(hashMap.size());
// loop HashMap
for (Entry<Dog, Integer> entry : hashMap.entrySet()) {
System.out.println(entry.getKey().toString() + " - " + entry.getValue());
}
}
@Test
public void fourth() {
// TODO Auto-generated method stub
class Dog {
String color;
Dog(String c) {
color = c;
}
public boolean equals(Object o) {
return ((Dog) o).color == this.color;
}
public int hashCode() {
return color.length();
}
public String toString() {
return color + " dog";
}
}
HashMap<Dog, Integer> hashMap = new HashMap<Dog, Integer>();
Dog d1 = new Dog("red");
Dog d2 = new Dog("black");
Dog d3 = new Dog("white");
Dog d4 = new Dog("white");
// 注意,我们错误的将”white dogs”添加了两次,但是HashMap却接受了两只”white dogs”。
// 这不合理(因为HashMap的键不应该重复),我们会搞不清楚真正有多少白色的狗存在。 五只呢?还是二十只
hashMap.put(d1, 10);
hashMap.put(d2, 15);
hashMap.put(d3, 5);
hashMap.put(d4, 20);
// print size
System.out.println(hashMap.size());
// loop HashMap
for (Entry<Dog, Integer> entry : hashMap.entrySet()) {
System.out.println(entry.getKey().toString() + " - " + entry.getValue());
}
}
@Test
public void fifth() {
// TreeMap的键按顺序排列。让我们先看个例子看看什么叫作“键按顺序排列”
class Dog {
String color;
Dog(String c) {
color = c;
}
public boolean equals(Object o) {
return ((Dog) o).color == this.color;
}
public int hashCode() {
return color.length();
}
public String toString() {
return color + " dog";
}
}
Dog d1 = new Dog("red");
Dog d2 = new Dog("black");
Dog d3 = new Dog("white");
Dog d4 = new Dog("white");
TreeMap<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
treeMap.put(d1, 10);
treeMap.put(d2, 15);
treeMap.put(d3, 5);
treeMap.put(d4, 20);
for (Entry<Dog, Integer> entry : treeMap.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
}
@Test
public void sixth() {
//我们来修改下Dog类,让它实现Comparable接口。
class Dog implements Comparable<Dog> {
String color;
int size;
Dog(String c,int size) {
this.color = c;
this.size = size;
}
public String toString() {
return color + " dog";
}
@Override
public int hashCode() {
return 1;
}
@Override
public boolean equals(Object obj) {
return false;
}
@Override
public int compareTo(Dog o) {
return o.size - this.size;
}
}
Dog d1 = new Dog("red", 30);
Dog d2 = new Dog("black", 20);
Dog d3 = new Dog("white", 10);
Dog d4 = new Dog("white", 10);
TreeMap<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
treeMap.put(d1, 10);
treeMap.put(d2, 15);
treeMap.put(d3, 5);
treeMap.put(d4, 20);
for (Entry<Dog, Integer> entry : treeMap.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
/**
* 如果我们将“Dog d4 = new Dog(“white”, 10);”替换成“Dog d4 = new Dog(“white”, 40);”,那么输出会变成:
* white dog - 20
* red dog - 10
* black dog - 15
* white dog - 5
* 这是因为TreeMap使用compareTo()方法来比较键值的大小,size不相等的狗是不同的狗。
*/
//再次和hashmap作比较,发现对于hashmap来说的相同指的是先要hashcode相同,再去调用该类的equals方法比较是不是一样的,来确定键是否相同,
//而TreeMap只去调用实现的Comparable接口的方法确定建值是否一样
HashMap<Dog, Integer> hashMap = new HashMap<Dog, Integer>();
// 注意,我们错误的将”white dogs”添加了两次,但是HashMap却接受了两只”white dogs”。
// 这不合理(因为HashMap的键不应该重复),我们会搞不清楚真正有多少白色的狗存在。 五只呢?还是二十只
hashMap.put(d1, 10);
hashMap.put(d2, 15);
hashMap.put(d3, 5);
hashMap.put(d4, 20);
// print size
System.out.println(hashMap.size());
// loop HashMap
for (Entry<Dog, Integer> entry : hashMap.entrySet()) {
System.out.println(entry.getKey().toString() + " - " + entry.getValue());
}
/**
* Java文档写道:
* HashMap类和Hashtable类几乎相同,不同之处在于HashMap是不同步的,也允许接受null键和null值。
* LinkedHashMap是HashMap的子类,所以LinkedHashMap继承了HashMap的一些属性,它在HashMap基础上增加的特性就是保存了插入对象的顺序。
*/
}
}
关于java 集合的六项讨论
最新推荐文章于 2023-10-30 23:24:16 发布