1.0.0 Summary

Tittle:【Java】-NO.16.EBook.4.Java.1.008-【疯狂Java讲义第3版 李刚】- 集合

Style:EBook

Series:Java

Since:2017-09-22

End:....

Total Hours:...

Degree Of Diffculty:2

Degree Of Mastery:2

Practical Level:2

Desired Goal:2

Archieve Goal:....

Gerneral Evaluation:...

Writer:kingdelee

Related Links:

http://www.cnblogs.com/kingdelee/

1.

1.Iterator在迭代的过程中,不允许添加/删除对象,可以修改对象

2.想要在迭代中过滤/删除某个元素,使用Predicate

public class PredicateTest
{
public static void main(String[] args)
{
// 创建一个集合
Collection books = new HashSet();
books.add(new String("轻量级Java EE企业应用实战"));
books.add(new String("疯狂Java讲义"));
books.add(new String("疯狂iOS讲义"));
books.add(new String("疯狂Ajax讲义"));
books.add(new String("疯狂Android讲义"));
// 使用Lambda表达式(目标类型是Predicate)过滤集合
books.removeIf(ele -> ((String)ele).length() < 10);
System.out.println(books);
}
}

  

public class PredicateTest2
{
public static void main(String[] args)
{
// 创建books集合、为books集合添加元素的代码与前一个程序相同。
Collection books = new HashSet();
books.add(new String("轻量级Java EE企业应用实战"));
books.add(new String("疯狂Java讲义"));
books.add(new String("疯狂iOS讲义"));
books.add(new String("疯狂Ajax讲义"));
books.add(new String("疯狂Android讲义"));
// 统计书名包含“疯狂”子串的图书数量
System.out.println(calAll(books , ele->((String)ele).contains("疯狂")));
// 统计书名包含“Java”子串的图书数量
System.out.println(calAll(books , ele->((String)ele).contains("Java")));
// 统计书名字符串长度大于10的图书数量
System.out.println(calAll(books , ele->((String)ele).length() > 10));
}
public static int calAll(Collection books , Predicate p)
{
int total = 0;
for (Object obj : books)
{
// 使用Predicate的test()方法判断该对象是否满足Predicate指定的条件
if (p.test(obj))
{
total ++;
}
}
return total;
}
}

3.Stream提供了常用的几个数据流的操作

public class IntStreamTest
{
public static void main(String[] args)
{
IntStream is = IntStream.builder()
.add(20)
.add(13)
.add(-2)
.add(18)
.build();
// 下面调用聚集方法的代码每次只能执行一个
System.out.println("is所有元素的最大值:" + is.max().getAsInt());
System.out.println("is所有元素的最小值:" + is.min().getAsInt());
System.out.println("is所有元素的总和:" + is.sum());
System.out.println("is所有元素的总数:" + is.count());
System.out.println("is所有元素的平均值:" + is.average());
System.out.println("is所有元素的平方是否都大于20:"
+ is.allMatch(ele -> ele * ele > 20));
System.out.println("is是否包含任何元素的平方大于20:"
+ is.anyMatch(ele -> ele * ele > 20));
// 将is映射成一个新Stream,新Stream的每个元素是原Stream元素的2倍+1
IntStream newIs = is.map(ele -> ele * 2 + 1);
// 使用方法引用的方式来遍历集合元素
newIs.forEach(System.out::println); // 输出41 27 -3 37
}
}

中间方法:

filter(Predicate predicate):

mapToXxxx(ToXxxFunction mapper):一对一进行转换

peek(Consumer action):

distinct()::

sorted():

limit(long maxSize)

末端方法:

forEach(Consumer action):

toArray():

min():

max():

count():

anyMatch(Predicate predicate)

findFirst():

findAny();

public class CollectionStream
{
public static void main(String[] args)
{
// 创建books集合、为books集合添加元素的代码与8.2.5小节的程序相同。
Collection books = new HashSet();
books.add(new String("轻量级Java EE企业应用实战"));
books.add(new String("疯狂Java讲义"));
books.add(new String("疯狂iOS讲义"));
books.add(new String("疯狂Ajax讲义"));
books.add(new String("疯狂Android讲义"));
// 统计书名包含“疯狂”子串的图书数量
System.out.println(books.stream().filter(ele->((String)ele).contains("疯狂")).count()); // 输出4
// 统计书名包含“Java”子串的图书数量
System.out.println(books.stream().filter(ele->((String)ele).contains("Java") ).count()); // 输出2
// 统计书名字符串长度大于10的图书数量
System.out.println(books.stream().filter(ele->((String)ele).length() > 10).count()); // 输出2
// 先调用Collection对象的stream()方法将集合转换为Stream,
// 再调用Stream的mapToInt()方法获取原有的Stream对应的IntStream
books.stream().mapToInt(ele -> ((String)ele).length())// 调用forEach()方法遍历IntStream中每个元素
.forEach(System.out::println);// 输出8 11 16 7 8 List<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(3);
list.add(2);
list.add(4);
list.add(4);
list.add(5);
list.add(5);
list.add(5);
System.out.println("--------1");
list.stream().filter(f -> f == 3).forEach(System.out::println);
System.out.println("--------2");
list.stream().distinct().forEach(System.out::println);
System.out.println("--------3");
list.stream().sorted().forEach(System.out::println);
System.out.println("--------4");
System.out.println(list.stream().min((a, b) -> a - b).get());
System.out.println("--------5");
list.stream().limit(5).forEach(System.out::println);
System.out.println(list.stream().count());
System.out.println(list.stream().anyMatch(a -> a == 5));
System.out.println(list.stream().findAny().get());
System.out.println(list.stream().findAny().get());
list.stream().mapToInt(a -> a*10).forEach(System.out::println);
list.stream().map(a -> a * a).forEach(System.out::println);
// list.stream().flatMap((a, b) -> a * b).forEach(System.out::println); }
}

  

4. Set:

Set实际上就是Collection,只是不允许添加重复元素。

HashSet、TreeSet、EnumSet

4.1 HashSet:

Hash排序

非同步

可以存null

比较集合中的元素是否相等的充要条件是,对应的hashcode()与equals()都要相等

// 1.判断Set集合中两个对象相等的条件是,equals和hashcode都要一样。
// 类A的equals方法总是返回true,但没有重写其hashCode()方法
class A
{
public boolean equals(Object obj)
{
return true;
}
}
// 类B的hashCode()方法总是返回1,但没有重写其equals()方法
class B
{
public int hashCode()
{
return 1;
}
}
// 类C的hashCode()方法总是返回2,且重写其equals()方法总是返回true
class C
{
public int hashCode()
{
return 2;
}
public boolean equals(Object obj)
{
return true;
}
}
public class HashSetTest
{
public static void main(String[] args)
{
HashSet books = new HashSet();
// 分别向books集合中添加两个A对象,两个B对象,两个C对象
books.add(new A());
books.add(new A());
books.add(new B());
books.add(new B());
books.add(new C());
books.add(new C());
books.forEach(System.out::println);
}
} //com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.B@1
//com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.B@1
//com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.A@610455d6
//com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.C@2
//com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.A@511d50c0

  

// 1. HashSet查找/删除元素的时候,是根据hashcode去操作的,所以有规律的重写hashcode可以避免某个撞桶
class R
{
int count;
int count2;
public R(int count)
{
this.count = count;
} public R(int count, int count2) {
this.count = count;
this.count2 = count2;
} // public String toString()
// {
// return "R[count:" + count + "]";
// } @Override
public String toString() {
return "R{" +
"count=" + count +
", count2=" + count2 +
'}';
} public boolean equals(Object obj)
{
if(this == obj)
return true;
if (obj != null && obj.getClass() == R.class)
{
R r = (R)obj;
return this.count == r.count;
}
return false;
}
public int hashCode()
{
return this.count;
}
}
public class HashSetTest2
{
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new R(5, 1));
hs.add(new R(-3, 2));
hs.add(new R(9, 3));
hs.add(new R(-2, 4));
// 打印HashSet集合,集合元素没有重复
System.out.println(hs);
// 取出第一个元素
Iterator it = hs.iterator();
R first = (R)it.next();
// 为第一个元素的count实例变量赋值
first.count = -3; // ①
// 再次输出HashSet集合,集合元素有重复元素
System.out.println(hs);
// 删除count为-3的R对象
hs.remove(new R(-3)); // ②
// 可以看到被删除了一个R元素
System.out.println(hs);
System.out.println("hs是否包含count为-3的R对象?"
+ hs.contains(new R(-3))); // 输出false
System.out.println("hs是否包含count为-2的R对象?"
+ hs.contains(new R(-2))); // 输出false
System.out.println("hs是否包含count为5的R对象?"
+ hs.contains(new R(5))); // 输出false
}
}

  

6.LinkHashSet:

LinkHashSet是HashSet的子类,根据hashcode决定存储位置,并通过链表维护元素次序使得元素插入有序。故可以有序的迭代读取元素。

7.TreeSet:

TreeSet是SortedSet接口的实现类,采用红黑树结构存储。排序规则:自然排序、自定义排序。

应注意:

7.1 TreeSet中的对象,应该是同一类型或者父子关系,且实现了Comapble接口。

7.2 TreeSet中的对象,应实现Comaprable接口,否则再加入第二个元素时,因为排序会调用Comaprable所以会报错。

7.3 TreeSet判断是否为同一对象,取决于compareTo()是否返回0

class A1 implements Comparable{

	@Override
public int compareTo(Object o) {
return 0;
}
}
class B1 extends A1{ }
public class TreeSetErrorTest2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
// 向TreeSet集合中添加两个对象
// ts.add(new String("疯狂Java讲义"));
// ts.add(new Date()); // ①
ts.add(new A1()); // ①
ts.add(new B1()); // ①
}
}

  

// 1. 当Set中的对象影响compareTo的元素被修改后,对该对象的删除和查找都将失效,而其他未被修改的对象正常。故不宜修改。
class R2 implements Comparable
{
int count;
public R2(int count)
{
this.count = count;
}
public String toString()
{
return "R[count:" + count + "]";
}
// 重写equals方法,根据count来判断是否相等
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if(obj != null && obj.getClass() == R2.class)
{
R2 r = (R2)obj;
return r.count == this.count;
}
return false;
}
// 重写compareTo方法,根据count来比较大小
public int compareTo(Object obj)
{
R2 r = (R2)obj;
return count > r.count ? 1 :
count < r.count ? -1 : 0;
}
}
public class TreeSetTest3
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add(new R2(5));
ts.add(new R2(-3));
ts.add(new R2(9));
ts.add(new R2(-2));
// 打印TreeSet集合,集合元素是有序排列的
System.out.println(ts); // ①
// 取出第一个元素
R2 first = (R2)ts.first();
// 对第一个元素的count赋值
first.count = 20;
// 取出最后一个元素
R2 last = (R2)ts.last();
// 对最后一个元素的count赋值,与第二个元素的count相同
last.count = -2;
// 再次输出将看到TreeSet里的元素处于无序状态,且有重复元素
System.out.println(ts); // ②
// 删除实例变量被改变的元素,删除失败
System.out.println(ts.remove(new R2(-2))); // ③
System.out.println(ts);
// 删除实例变量没有被改变的元素,删除成功
System.out.println(ts.remove(new R2(5))); // ④
System.out.println(ts);
}
}

  

// 1.定制排序
class M
{
int age;
public M(int age)
{
this.age = age;
}
public String toString()
{
return "M[age:" + age + "]";
}
}
public class TreeSetTest4
{
public static void main(String[] args)
{
// 此处Lambda表达式的目标类型是Comparator
TreeSet ts = new TreeSet((o1 , o2) ->
{
M m1 = (M)o1;
M m2 = (M)o2;
// 根据M对象的age属性来决定大小,age越大,M对象反而越小
return m1.age > m2.age ? -1
: m1.age < m2.age ? 1 : 0;
});
ts.add(new M(5));
ts.add(new M(-3));
ts.add(new M(9));
System.out.println(ts);
}
}

  

8.EmunSet

EmunSet

enum Season
{
SPRING,SUMMER,FALL,WINTER
}
public class EnumSetTest
{
public static void main(String[] args)
{
// 创建一个EnumSet集合,集合元素就是Season枚举类的全部枚举值
EnumSet es1 = EnumSet.allOf(Season.class);
System.out.println(es1); // 输出[SPRING,SUMMER,FALL,WINTER]
// 创建一个EnumSet空集合,指定其集合元素是Season类的枚举值。
EnumSet es2 = EnumSet.noneOf(Season.class);
System.out.println(es2); // 输出[]
// 手动添加两个元素
es2.add(Season.WINTER);
es2.add(Season.SPRING);
es2.add(Season.SPRING);
System.out.println(es2); // 输出[SPRING,WINTER]
// 以指定枚举值创建EnumSet集合
EnumSet es3 = EnumSet.of(Season.SUMMER , Season.WINTER);
System.out.println(es3); // 输出[SUMMER,WINTER]
EnumSet es4 = EnumSet.range(Season.SUMMER , Season.WINTER);
System.out.println(es4); // 输出[SUMMER,FALL,WINTER]
// 新创建的EnumSet集合的元素和es4集合的元素有相同类型,
// es5的集合元素 + es4集合元素 = Season枚举类的全部枚举值
EnumSet es5 = EnumSet.complementOf(es4);
System.out.println(es5); // 输出[SPRING]
}
}

  

public class EnumSetTest2
{
public static void main(String[] args)
{
Collection c = new HashSet();
c.clear();
c.add(Season.FALL);
c.add(Season.SPRING);
// 复制Collection集合中所有元素来创建EnumSet集合
EnumSet enumSet = EnumSet.copyOf(c); // ①
System.out.println(enumSet); // 输出[SPRING,FALL]
c.add("疯狂Java讲义");
c.add("轻量级Java EE企业应用实战");
// 下面代码出现异常:因为c集合里的元素不是全部都为枚举值
enumSet = EnumSet.copyOf(c); // ②
}
}

  

各种Set的实现类比较:

8.1.在add(), get()操作,性能 HashSet > TreeSet,理由TreeSet需要额外的红黑树来维持次序。

8.2.在add(), delete()操作,性能 HashSet > LinkedHashSet,遍历操作,性能 HashSet < LinkedHashSet,理由 LinkedHashSet有链表维护次序。

8.3,EnumSet是性能最好的,只能保存同一种枚举类的值作为集合元素。

8.4.HashSet,TreeSet,EnumSet都不是线程安全的,同步时应使用类似:

TreeSet<Object> objects = new TreeSet<>();
Collections.synchronizedNavigableSet(objects);

9. List

1.根据元素的equals判断List中两个元素是否相等,如果重写某元素equals=true,则该元素与集合中的任意一元素恒等。

// 1.根据元素的equals判断List中两个元素是否相等,如果重写某元素equals=true,则该元素与集合中的任意一元素恒等。
class A
{
public boolean equals(Object obj)
{
return true;
}
}
public class ListTest2
{
public static void main(String[] args)
{
List books = new ArrayList();
books.add(new String("轻量级Java EE企业应用实战"));
books.add(new String("疯狂Java讲义"));
books.add(new String("疯狂Android讲义"));
System.out.println(books);
// 删除集合中A对象,将导致第一个元素被删除
books.remove(new A()); // ①
System.out.println(books);
// 删除集合中A对象,再次删除集合中第一个元素
books.remove(new A()); // ②
System.out.println(books);
}
}
//[轻量级Java EE企业应用实战, 疯狂Java讲义, 疯狂Android讲义]
//[疯狂Java讲义, 疯狂Android讲义]
//[疯狂Android讲义]

  

public class ListTest3
{
public static void main(String[] args)
{
List books = new ArrayList();
// 向books集合中添加4个元素
books.add(new String("轻量级Java EE企业应用实战"));
books.add(new String("疯狂Java讲义"));
books.add(new String("疯狂Android讲义"));
books.add(new String("疯狂iOS讲义"));
// 使用目标类型为Comparator的Lambda表达式对List集合排序
// [疯狂iOS讲义, 疯狂Java讲义, 疯狂Android讲义, 轻量级Java EE企业应用实战]
// books.sort((o1, o2)->((String)o1).length() - ((String)o2).length());
// [轻量级Java EE企业应用实战, 疯狂Android讲义, 疯狂Java讲义, 疯狂iOS讲义]
// books.sort((o1, o2)->((String)o2).length() - ((String)o1).length());
// [疯狂iOS讲义, 疯狂Java讲义, 疯狂Android讲义, 轻量级Java EE企业应用实战]
books.sort(Comparator.comparing(String::length));
System.out.println(books);
// 使用目标类型为UnaryOperator的Lambda表达式来替换集合中所有元素
// 该Lambda表达式控制使用每个字符串的长度作为新的集合元素
books.replaceAll(ele->((String)ele).length());
System.out.println(books); // 输出[7, 8, 11, 16] }
}

  

Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

// 1. Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
public class ListIteratorTest
{
public static void main(String[] args)
{ String[] books = {
"疯狂Java讲义", "疯狂iOS讲义",
"轻量级Java EE企业应用实战"
};
List bookList = new ArrayList();
for (int i = 0; i < books.length ; i++ )
{
bookList.add(books[i]);
} ListIterator lit = bookList.listIterator();
while (lit.hasNext())
{
System.out.println(lit.next());
lit.add("-------分隔符-------");
}
System.out.println("=======下面开始反向迭代=======");
while(lit.hasPrevious())
{
System.out.println(lit.previous());
}
}
}

  

10. Vector Stack ArrayList ArrayDeque

10.1 Vector是线程安全的,ArrayList是线程不安全的,然而,要保证线程安全,只需使用Collections.synchronizedList()即可,故Vector没卵用。

10.2 Vector是古老的类,存在诸多缺点,性能低下,远不如ArrayList,所以Vector应不使用。

10.3 Stack是Vector的子类,模拟实现栈结构,然而远不如ArrayDeque,故Stack应不使用。

10.4 特别注意 Arrays.ArrayList返回的是一个固定长度的数组,是Arrays里边的一个静态内部类,不是util包的ArrayList,故不能使用add remove等方法。

11. Queue

11.1 队列不允许随机访问,使用的是FIFO(先进先出)策略操作存储。

11.2 Deque是双端队列的接口,可以使用实现类ArrayDeqeue LinkedList同时操作两端,ArrayDeqeue既是队列也是栈。

11.3 PriorityQueue,queue中的异端,采取元素的大小而非FIFO的策略进行存储。

对于ArrayDeque:

入栈:

push、addFirst :加头,无返回,null会异常。

offerFirst:加头,有返回值,null会异常。调用addFirst。

add:加头,返回boolean,null会异常。

offer、offerLast:加尾,返回boolean,null会异常。

出栈:

pop、removeFirst:取头,删除。null会异常。

peek、peekFirst:取头,不删除。null返null。

peekLast:取尾,不删除。null返null

public class PriorityQueueTest
{
public static void main(String[] args)
{
PriorityQueue pq = new PriorityQueue();
// 下面代码依次向pq中加入四个元素
pq.offer(6);
pq.offer(-3);
pq.offer(20);
pq.offer(18);
// 输出pq队列,并不是按元素的加入顺序排列
System.out.println(pq); // 输出[-3, 6, 20, 18]
// 访问队列第一个元素,其实就是队列中最小的元素:-3
System.out.println(pq.poll());
}
} public class LinkedListTest
{
public static void main(String[] args)
{
LinkedList books = new LinkedList();
// 将字符串元素加入队列的尾部
books.offer("疯狂Java讲义");
// 将一个字符串元素加入栈的顶部
books.push("轻量级Java EE企业应用实战");
// 将字符串元素添加到队列的头部(相当于栈的顶部)
books.offerFirst("疯狂Android讲义");
// 以List的方式(按索引访问的方式)来遍历集合元素
for (int i = 0; i < books.size() ; i++ )
{
System.out.println("遍历中:" + books.get(i));
}
// 访问、并不删除栈顶的元素
System.out.println(books.peekFirst());
// 访问、并不删除队列的最后一个元素
System.out.println(books.peekLast());
// 将栈顶的元素弹出“栈”
System.out.println(books.pop());
// 下面输出将看到队列中第一个元素被删除
System.out.println(books);
// 访问、并删除队列的最后一个元素
System.out.println(books.pollLast());
// 下面输出:[轻量级Java EE企业应用实战]
System.out.println(books);
}
} public class ArrayDequeStack
{
public static void main(String[] args)
{
ArrayDeque stack = new ArrayDeque();
// 依次将三个元素push入"栈"
stack.push("1");
// stack.push("3");
// stack.push("4");
// stack.push("2");
// stack.push("5"); // add与Off是一样的方法
stack.addFirst("8");
stack.offer("8");
stack.add("8");
stack.addFirst("8");
stack.addLast("8");
stack.offer("8"); //
System.out.println(stack);
System.out.println(stack.peekLast());
System.out.println(stack.pop());
System.out.println(stack.peekLast());
System.out.println(stack);
}
} public class ArrayDequeQueue
{
public static void main(String[] args)
{
ArrayDeque queue = new ArrayDeque();
// 依次将三个元素加入队列
queue.offer("疯狂Java讲义");
queue.offer("轻量级Java EE企业应用实战");
queue.offer("疯狂Android讲义");
// 输出:[疯狂Java讲义, 轻量级Java EE企业应用实战, 疯狂Android讲义]
System.out.println(queue);
// 访问队列头部的元素,但并不将其poll出队列"栈",输出:疯狂Java讲义
System.out.println(queue.peek());
// 依然输出:[疯狂Java讲义, 轻量级Java EE企业应用实战, 疯狂Android讲义]
System.out.println(queue);
// poll出第一个元素,输出:疯狂Java讲义
System.out.println(queue.poll());
// 输出:[轻量级Java EE企业应用实战, 疯狂Android讲义]
System.out.println(queue);
}
}

  

12. ArrayList LinkedList

ArrayList 基于数组的线性表,以一块连续内存区保存所有元素,具有较好的随机访问效率。遍历使用get获取元素。

LinkedList 基于链表的线性表,在插入、删除元素时具有较好效率。遍历时使用Iterator。

13.Map

13.1 HashMap Hashtable

Hashtable与Vector一样都是过时的玩意,同步也没卵用,用 Collections.synchronizedMap() 就能够使HashMap具备同步效果。

class A
{
int count;
public A(int count)
{
this.count = count;
}
// 根据count的值来判断两个对象是否相等。
public boolean equals(Object obj)
{
if (obj == this)
return true;
if (obj != null && obj.getClass() == A.class)
{
A a = (A)obj;
return this.count == a.count;
}
return false;
}
// 根据count来计算hashCode值。
public int hashCode()
{
return this.count;
}
}
class B
{
// 重写equals()方法,B对象与任何对象通过equals()方法比较都返回true
public boolean equals(Object obj)
{
return true;
}
}
public class HashtableTest
{
public static void main(String[] args)
{
Hashtable ht = new Hashtable();
ht.put(new A(60000) , "疯狂Java讲义");
ht.put(new A(87563) , "轻量级Java EE企业应用实战");
ht.put(new A(1232) , new B());
System.out.println(ht);
// 只要两个对象通过equals比较返回true,
// Hashtable就认为它们是相等的value。
// 由于Hashtable中有一个B对象,
// 它与任何对象通过equals比较都相等,所以下面输出true。
System.out.println(ht.containsValue("测试字符串")); // ① 输出true
// 只要两个A对象的count相等,它们通过equals比较返回true,且hashCode相等
// Hashtable即认为它们是相同的key,所以下面输出true。
System.out.println(ht.containsKey(new A(87563))); // ② 输出true
// 下面语句可以删除最后一个key-value对
ht.remove(new A(1232)); //③
System.out.println(ht);
}
}

  

// 1.当用于equals判断的值被修改时,该元素就无法被操作
public class HashMapErrorTest
{
public static void main(String[] args)
{
HashMap ht = new HashMap();
// 此处的A类与前一个程序的A类是同一个类
ht.put(new A(60000) , "疯狂Java讲义");
ht.put(new A(87563) , "轻量级Java EE企业应用实战");
System.out.println("--------------1:" + ht);
// 获得Hashtable的key Set集合对应的Iterator迭代器
Iterator it = ht.keySet().iterator();
// 取出Map中第一个key,并修改它的count值
A first = (A)it.next();
first.count = 87563; // ①
// 输出{A@1560b=疯狂Java讲义, A@1560b=轻量级Java EE企业应用实战}
System.out.println("--------------2:" + ht);
// 只能删除没有被修改过的key所对应的key-value对
ht.remove(new A(87563)); System.out.println("--------------3:" + ht);
// 无法获取剩下的value,下面两行代码都将输出null。
System.out.println(ht.get(new A(87563))); // ② 输出null
System.out.println(ht.get(new A(60000))); // ③ 输出null
}
}
//--------------1:{com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@ea60=疯狂Java讲义, com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@1560b=轻量级Java EE企业应用实战}
//--------------2:{com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@1560b=疯狂Java讲义, com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@1560b=轻量级Java EE企业应用实战}
//--------------3:{com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@1560b=疯狂Java讲义}
//null
//null

  

13.2 LinkedHashMap

13.2.1 LinkedHashMap 是 HashMap的子类,如同LinkedHashSet是HashSet的子类一样,用双向链表维护key-value的顺序,使得迭代的顺序与插入的顺序是一致的。

13.2.2 LinkedHashMap 不用像HashMap一样靠hash控制key-value顺序,同时有避免TreeMap增加的成本,因为要维护插入顺序,故插入速度低于HashMap,但迭代速度要优于HashMap

public class LinkedHashMapTest
{
public static void main(String[] args)
{
LinkedHashMap scores = new LinkedHashMap();
scores.put("语文" , 80);
scores.put("英文" , 82);
scores.put("数学" , 76);
// 调用forEach方法遍历scores里的所有key-value对
scores.forEach((key, value) -> System.out.println(key + "-->" + value));
}
}

  

14. Properties

Properties是Hashtable的子类

public class PropertiesTest
{
public static void main(String[] args)
throws Exception
{
Properties props = new Properties();
// 向Properties中增加属性
props.setProperty("username" , "yeeku");
props.setProperty("password" , "123456");
// 将Properties中的key-value对保存到a.ini文件中
props.store(new FileOutputStream("a.ini")
, "comment line"); //①
// 新建一个Properties对象
Properties props2 = new Properties();
// 向Properties中增加属性
props2.setProperty("gender" , "male");
// 将a.ini文件中的key-value对追加到props2中
props2.load(new FileInputStream("a.ini") ); //②
System.out.println(props2);
}
}

  

15.SortedMap

SortedMap是Map的子类接口,TreeMap是接口SortedMap的实现类,与TreeSet的SortedSet关系一样,红黑树结构控制存储。

1.定制排序,传入Comparator的实现类实现compare(a,b)的方法

 2.自然排序,让TreeMap中的key元素对象实现Comparable的compareTo(O o)方法

class R implements Comparable
{
int count;
public R(int count)
{
this.count = count;
}
public String toString()
{
return "R[count:" + count + "]";
}
// 根据count来判断两个对象是否相等。
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj != null && obj.getClass() == R.class)
{
R r = (R)obj;
return r.count == this.count;
}
return false;
}
// 根据count属性值来判断两个对象的大小。
public int compareTo(Object obj)
{
R r = (R)obj;
return count > r.count ? 1 :
count < r.count ? -1 : 0;
}
}
// 1.定制排序,传入Comparator的实现类实现compare(a,b)的方法
// 2.自然排序,让TreeMap中的key元素对象实现Comparable的compareTo(O o)方法
public class TreeMapTest
{
public static void main(String[] args)
{
TreeMap tm = new TreeMap((a, b) -> (int)b - (int)a);
tm.put(new R(3) , "轻量级Java EE企业应用实战");
tm.put(new R(-5) , "疯狂Java讲义");
tm.put(new R(9) , "疯狂Android讲义");
System.out.println(tm);
// 返回该TreeMap的第一个Entry对象
System.out.println(tm.firstEntry());
// 返回该TreeMap的最后一个key值
System.out.println(tm.lastKey());
// 返回该TreeMap的比new R(2)大的最小key值。
System.out.println(tm.higherKey(new R(2)));
// 返回该TreeMap的比new R(2)小的最大的key-value对。
System.out.println(tm.lowerEntry(new R(2)));
// 返回该TreeMap的子TreeMap
System.out.println(tm.subMap(new R(-1) , new R(4)));
}
}

  

16.WeakHashMap

与HsahMap的区别在于,HashMap里边对key的存储是强引用,而WeakHashMap是弱引用。即进行GC后,WeakHashMap里边的key因为不是强引用,而有可能会回收。缓冲区的除外。

// 1.new String()只保留了弱引用,而""是字符串缓冲区的,不会被GC。
public class WeakHashMapTest
{
public static void main(String[] args)
{
WeakHashMap whm = new WeakHashMap();
// 将WeakHashMap中添加三个key-value对,
// 三个key都是匿名字符串对象(没有其他引用)
whm.put(new String("语文") , new String("良好"));
whm.put(new String("数学") , new String("及格"));
whm.put(new String("英文") , new String("中等"));
//将 WeakHashMap中添加一个key-value对,
// 该key是一个系统缓存的字符串对象。
whm.put("java" , new String("中等")); // ①
// 输出whm对象,将看到4个key-value对。
System.out.println(whm);
// 通知系统立即进行垃圾回收
System.gc();
System.runFinalization();
// 通常情况下,将只看到一个key-value对。
System.out.println(whm);
}
}
//{英文=中等, java=中等, 数学=及格, 语文=良好}
//{java=中等}

  

17.IdentityHashMap

IdentityHashMap 判断相等需要key1 == key2 严格相等才可以,而HashMap只需要key1和key2通过equals比较相等且hashcode相等。

public class IdentityHashMapTest
{
public static void main(String[] args)
{
IdentityHashMap ihm = new IdentityHashMap();
// 下面两行代码将会向IdentityHashMap对象中添加两个key-value对
ihm.put(new String("语文") , 89);
ihm.put(new String("语文") , 78);
// 下面两行代码只会向IdentityHashMap对象中添加一个key-value对
ihm.put("java" , 93);
ihm.put("java" , 98);
System.out.println(ihm);
}
}
//{语文=78, java=98, 语文=89}

  

18.EnumMap

Enum内部以数组实现,所以非常高效

enum Season
{
SPRING,SUMMER,FALL,WINTER
}
public class EnumMapTest
{
public static void main(String[] args)
{
// 创建EnumMap对象,该EnumMap的所有key都是Season枚举类的枚举值
EnumMap enumMap = new EnumMap(Season.class);
enumMap.put(Season.SUMMER , "夏日炎炎");
enumMap.put(Season.SPRING , "春暖花开");
System.out.println(enumMap);
}
}

  

桶概念:

HashMap和HashSet通过hash算法存储key元素,而这个key有可能会有重复的情况,所以用了一个集合桶去装这些重复的hash值的元素。相同的桶里边的元素之间是通过链表实现的,必须按顺序存储,故桶内的查找效率就会低了。

【Java】-NO.16.EBook.4.Java.1.008-【疯狂Java讲义第3版 李刚】- 集合/容器的更多相关文章

  1. 【Java】-NO.16.EBook.4.Java.1.011-【疯狂Java讲义第3版 李刚】- AWT

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.011-[疯狂Java讲义第3版 李刚]-  AWT Style:EBook Series:Java ...

  2. 【Java】-NO.16.EBook.4.Java.1.012-【疯狂Java讲义第3版 李刚】- Swing

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.011-[疯狂Java讲义第3版 李刚]-  Swing Style:EBook Series:Jav ...

  3. 【Java】-NO.16.EBook.4.Java.1.012-【疯狂Java讲义第3版 李刚】- JDBC

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.012-[疯狂Java讲义第3版 李刚]-  JDBC Style:EBook Series:Java ...

  4. 【Java】-NO.16.EBook.4.Java.1.005-【疯狂Java讲义第3版 李刚】- 枚举

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.005-[疯狂Java讲义第3版 李刚]- 枚举 Style:EBook Series:Java Si ...

  5. 【Java】-NO.16.EBook.4.Java.1.006-【疯狂Java讲义第3版 李刚】- 垃圾回收

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.006-[疯狂Java讲义第3版 李刚]- 垃圾回收 Style:EBook Series:Java ...

  6. 【Java】-NO.16.EBook.4.Java.1.007-【疯狂Java讲义第3版 李刚】- Java基础类

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.007-[疯狂Java讲义第3版 李刚]-  Java基础类 Style:EBook Series:J ...

  7. 【Java】-NO.16.EBook.4.Java.1.009-【疯狂Java讲义第3版 李刚】- 泛型

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.009-[疯狂Java讲义第3版 李刚]- 泛型 Style:EBook Series:Java Si ...

  8. 【Java】-NO.16.EBook.4.Java.1.010-【疯狂Java讲义第3版 李刚】- 异常

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.010-[疯狂Java讲义第3版 李刚]- 异常 Style:EBook Series:Java Si ...

  9. 【Java】-NO.16.EBook.4.Java.1.001-【疯狂Java讲义第3版 李刚】- UML

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.001-[疯狂Java讲义第3版 李刚]- Style:EBook Series:Java Since ...

随机推荐

  1. HTML+CSS:圆形和圆角图片格式

    效果展示 实现代码 <!DOCTYPE html> <html> <head> <title>JcMan</title> <style ...

  2. ModelAttribue注解的使用

    Spring中有很多注解,如RequestParam,PathVarible,SesstionAttribute,这些在开发是多尝试一下,可能用得到,ModelAttribute用的还挺多,可以以此为 ...

  3. xss攻击问题以及如何防范

    当用户提交评论的时候,比如如下评论内容 111 <scripy>alert(111);</scripy> 这样当现实评论的时候会先弹出111弹框,再显示评论.这就是xss攻击. ...

  4. Nodejs----注册登录

    这个小应用使用到了node.js  bootstrap  express  以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...

  5. Men and women can't be 'just friends

    Men and women can't be 'just friends' Can heterosexual men and women ever be "just friends" ...

  6. MyEclipse中的几种查找方法

    在编程中常常需要用到查找功能,这里根据日常的使用总结一下常用的集中查找方法 Ctrl+H:在MyEclipse中打开Search弹出框,或者在菜单中打开Search弹出框, 定位到 File Sear ...

  7. python中的os

    import sys, os print(__file__) # 绝对路径,实际是文件名 /Users/majianyu/Desktop/test/bin/bin.py print(os.path.a ...

  8. Srt字幕文件解析

    // // ViewController.m // 字幕解析 // // Created by admin on 2018/8/30. // Copyright © 2018年 admin. All ...

  9. angular 上传图像的使用总结

    AngularJS 的文件上传控件有两个:(1) angular-file-upload:https://github.com/nervgh/angular-file-upload(2) ng-fil ...

  10. ARCSDE直连Oracle时出现错误Failed to connect to the specified server. Underlying DBMS error[ORA-12154: TNS:could not resolve the connect identifier specified. No extended error]

    买了新笔记本,装软件. 在ARCSDE直连Oracle时遇到问题. esri官网给的解释是因为安装arcgis时安装目录里有特殊字符(详见:https://support.esri.com/en/te ...