泛型:

jdk1.5出现的安全机制。

好处:

1,将运行时期的问题ClassCastException转到了编译时期。

2,避免了强制转换的麻烦。

<>:什么时候用?当操作的引用数据类型不确定的时候。就使用<>。将要操作的引用数据类型传入即可.

其实<>就是一个用于接收具体引用数据类型的参数范围。

在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型 。

泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。

运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。

为什么擦除呢?因为为了兼容运行的类加载器。

java程序运行要靠虚拟机去启动一个类装载器。

类加载器:专门用于读取类文件,并解析类文件,并且把这个文件加载进入内存的一个程序。

1.4版本和1.5版本都是用的这个类加载器。

我们把类型在编译时期进行检查,如果检查之后是没有错误的就可以把这个泛型去掉。

里面的类型就统一了,我们还想用以前的这个类加载器,解析,加载进内存。

以前的加载器是没有见过泛型的。所以为了兼容运行的类加载器。

泛型的补偿:在运行时,通过获取元素的类型进行转换动作。不用使用者再强制转换了。

泛型的通配符:? 未知类型。

泛型的限定:

? extends E: 接收E类型或者E的子类型对象。上限。

一般存储对象的时候用。比如 添加元素 addAll.

? super E: 接收E类型或者E的父类型对象。 下限。

一般取出对象的时候用。比如比较器。

用大写的E,因为泛型中都是接收的引用数据类型,引用数据类型不是类就是借口,或者数组,他们的书写方式都是首字母大写.

E就是个参数,代表Elements.

早期没有泛型用的是Object,进行自动类型提升,当想用到集合中的元素时候要进行强制类型转换.

泛型尖括号中可以有多个类型;

Tool<String,Demo,Person,Integer> t = new Tool<String,Demo,Person,Integer>;

泛型中不能有基础数据类型,都是引用数据类型,可以是数组。

===========================================================

集合的一些技巧:

需要唯一吗?

需要:Set

需要制定顺序:

需要: TreeSet

不需要:HashSet

但是想要一个和存储一致的顺序(有序):LinkedHashSet

不需要:List

需要频繁增删吗?

需要:LinkedList

不需要:ArrayList

如何记录每一个容器的结构和所属体系呢?

看名字!

List

|--ArrayList

|--LinkedList

Set

|--HashSet

|--TreeSet

后缀名就是该集合所属的体系。

前缀名就是该集合的数据结构。

看到array:就要想到数组,就要想到查询快,有角标.

看到link:就要想到链表,就要想到增删快,就要想要 add get remove+frist last的方法

看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashcode方法和equals方法。

看到tree:就要想到二叉树,就要想要排序,就要想到两个接口Comparable,Comparator 。

而且通常这些常用的集合容器都是不同步的。

============================================

Map:一次添加一对元素。Collection 一次添加一个元素。

Map也称为双列集合,Collection集合称为单列集合。

其实map集合中存储的就是键值对。

map集合中必须保证键的唯一性。

常用方法:

1,添加。

value put(key,value):返回前一个和key关联的值,如果没有返回null.

2,删除。

void  clear():清空map集合。

value remove(key):根据指定的key删除这个键值对。

3,判断。

boolean containsKey(key): 如果此映射包含指定键的映射关系,则返回 true

boolean containsValue(value): 如果此映射将一个或多个键映射到指定值,则返回 true

boolean isEmpty();

4,获取。

value get(key):通过键获取值,如果没有该键返回null。

当然可以通过返回null,来判断是否包含指定键。

int size(): 获取键值对的个数。

Map常用的子类:

|--Hashtable :内部结构是哈希表,是同步的。不允许null作为键,null作为值。

|--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。

|--HashMap : 内部结构是哈希表,不是同步的。允许null作为键,null作为值。

|--TreeMap : 内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。

Map和Collection没有关系,Collection有迭代器,Map没有。

keySet

Set<K> keySet()

返回此映射中包含的键的 Set 视图。

keySet()→键的集合。

取出Map集合中所有的键值对第一种方法。

MapDemo1.java

 import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set; public class MapDemo1 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
method_2(map);
} public static void method_2(Map<Integer,String> map){
map.put(8,"zhaoliu");
map.put(2,"zhaoliu");
map.put(7,"xiaoqiang");
map.put(6,"wangcai");
//取出map中的所有元素。
//原理,通过keySet方法获取map中所有的键所在的Set集合,在通过Set的迭代器获取到每一个键,
//再对每一个键通过map集合的get方法获取其对应的值即可。 Set<Integer> keySet = map.keySet();
Iterator<Integer> it = keySet.iterator(); while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println(key+":"+value);
}
}
}

Map定义的时候就键就是Integer类型.

程序输出:

2:zhaoliu

6:wangcai

7:xiaoqiang

8:zhaoliu

嵌套类摘要

static interface  Map.Entry<K,V>  映射项(键-值对)。

entrySet 

Set<Map.Entry<K,V>> entrySet()

返回此映射中包含的映射关系的 Set 视图。

取出Map集合中所有的键值对第二种方法。

MapDemo2.java

 public class MapDemo2 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
method_2(map);
} public static void method_2(Map<Integer,String> map){
map.put(8,"zhaoliu");
map.put(2,"zhaoliu");
map.put(7,"xiaoqiang");
map.put(6,"wangcai");
/*
* 通过Map转成set就可以迭代。
* 找到了另一个方法。entrySet。
* 该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型(结婚证)
*/
Set<Map.Entry<Integer, String>> entrySet = map.entrySet(); Iterator<Map.Entry<Integer, String>> it = entrySet.iterator(); while(it.hasNext()){
Map.Entry<Integer, String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::::"+value);
}
}
}
interface MyMap{
public static interface MyEntry{//内部接口
void get();
}
}
class MyDemo implements MyMap.MyEntry{
public void get(){}
}
class Outer{
static class Inner{
static void show(){}
}
}

输出结果:

程序输出:
2::::zhaoliu
6::::wangcai
7::::xiaoqiang
8::::zhaoliu

对比keySet和entrySet的不同:

entrySet

 Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
Iterator<Map.Entry<Integer, String>> it = entrySet.iterator(); while(it.hasNext()){
Map.Entry<Integer, String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::::"+value);
}

keySet

 Set<Integer> keySet = map.keySet();
Iterator<Integer> it = keySet.iterator();
while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println(key+":"+value);
}

取出Map集合中所有的键值对第三种方法。

Collection<V>

values()
          返回此映射中包含的值的
Collection 视图。

这个地方虽然和前面两个地方挺像,但是这个地方仅仅是练习的Map接口中的values()方法。(其实是继承Map接口的HashMap中的values()方法。接口中的方法都是抽象方法)。

MapDemo3.java

 public class MapDemo3 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
method_2(map);
}
public static void method_2(Map<Integer,String> map){
map.put(8,"zhaoliu");
map.put(2,"zhaoliu");
map.put(7,"xiaoqiang");
map.put(6,"wangcai");
Collection<String> values = map.values();
Iterator<String> it2 = values.iterator();
while(it2.hasNext()){
System.out.println(it2.next());
}
}
}

程序输出:

程序输出:
zhaoliu
wangcai
xiaoqiang
zhaoliu

Map常用的子类:

|--Hashtable :内部结构是哈希表,是同步的。不允许null作为键,null作为值。

|--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。

|--HashMap : 内部结构是哈希表,不是同步的。允许null作为键,null作为值。

|--TreeMap : 内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。

后续出现的都是不同步的,效率高的。

Set集合的底层代码就是Map来实现的。
Map就能解决这个问题了,为什么还要有Set,是因为,为了保证单列集合中还能元素的唯一性,才出现的。

HashSet

此类实现 Set 接口,由哈希表(实际上是一个 HashMap
实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用
null 元素。


Hashtable<K,V>

直接已知子类:

Properties

这个子类非常常用,可以和IO技术相结合。经常使用。

地址值:

如果仅仅是简单的一个城市就用字符串表示,如果是各个层级都有就用对象进行封装。

HashMapDemo.java

 public class HashMapDemo {
public static void main(String[] args) {
/*
* 将学生对象和学生的归属地通过键与值存储到map集合中。
*
*/
HashMap<Student,String> hm = new HashMap<Student,String>();
hm.put(new Student("lisi",38),"北京");
hm.put(new Student("zhaoliu",24),"上海");
hm.put(new Student("xiaoqiang",31),"沈阳");
hm.put(new Student("wangcai",28),"大连");
hm.put(new Student("zhaoliu",24),"铁岭"); // Set<Student> keySet = hm.keySet();
// Iterator<Student> it = keySet.iterator();
       //这就是前面讲过的“匿名对象”,如果new一个对象就用一次,那就直接用匿名对象就可以。
         Iterator<Student> it = hm.keySet().iterator();

         while(it.hasNext()){
Student key = it.next();
String value = hm.get(key);
System.out.println(key.getName()+":"+key.getAge()+"---"+value);
}
}
}

结果输出:

xiaoqiang:31---沈阳
zhaoliu:24---铁岭
lisi:38---北京
zhaoliu:24---上海
wangcai:28---大连

很明显这种输出是错误的,因为键是不能重复的,这个和当时学Set中的情况一样,Set中也是不允许出现重复的值。

解决办法:

键既然存储到了哈希表中,那么要去具备hashcode和equals方法和自己的内容,所以要在Student类中要去覆写hashcode和equals方法。

关于JDK中的集合总结(三)的更多相关文章

  1. Java中的集合(三)继承Collection的Queue接口

    Java中的集合(三)继承Collection的Queue接口 一.Queue介绍 Queue接口继承自Collection接口,是Java中定义的一种队列数据结构,元素是有序的(按插入顺序排序),先 ...

  2. 关于JDK中的集合总结(二)

    1.2版本的JDK才出现的java集合框架. 下面介绍说一下Vector的一些特点. import java.util.Enumeration; import java.util.Iterator; ...

  3. java中遍历集合的三种方式

    第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ...

  4. 关于JDK中的集合总结(一)

    静态方法只能继承,不能重写(Override). StringBufffer,数组,对象 都是容器. 加入数据,“zhangsan” true ,67, 三个数据数据类型不同,不能用数组作为集合,只能 ...

  5. Java中List集合的三种遍历方式(全网最详)

    List集合在Java日常开发中是必不可少的,只要懂得运用各种各样的方法就可以大大提高我们开发的效率,适当活用各种方法才会使我们开发事半功倍. 我总结了三种List集合的遍历方式,下面一一来介绍. 首 ...

  6. Java中的集合(四)PriorityQueue常用方法

    Java中的集合(四)PriorityQueue常用方法 PriorityQueue的基本概念等都在上一篇已说明,感兴趣的可以点击 Java中的集合(三)继承Collection的Queue接口 查看 ...

  7. Java中的集合(六)继承Collection的Set接口

    Java中的集合(六)继承Collection的Set接口 一.Set接口的简介 Set接口和List接口都是继承自Collection接口,它与Collection接口中功能基本一致,并没有对Col ...

  8. 没有人比我更会使用集合!对, 是dart中的集合

    目录 简介 List的使用 Set的使用 Map的使用 常见的集合方法 总结 简介 dart中的集合有三个,分别是list,set和map.dart在dart:core包中提供了对于这三种集合非常有用 ...

  9. 集合篇 —— Collection(1):JDK 中的重复实现问题

    1.      问题的提出 在 Java 的集合体系当中,无论是 List(列表)还是 Set(集),在设计的时候都存在一个很奇怪的现象:这两种集合的接口,Java 都为其设计了抽象类 Abstrac ...

随机推荐

  1. quartz 时间配置规则

    quartz 时间配置规则 格式: [秒] [分] [小时] [日] [月] [周] [年]  序号 说明  是否必填  允许填写的值 允许的通配符  1  秒  是  0-59    , - * / ...

  2. HDU 1213 How Many Tables (并查集)

    How Many Tables 题目链接: http://acm.hust.edu.cn/vjudge/contest/123393#problem/C Description Today is Ig ...

  3. Spring EL hello world example

    The Spring EL is similar with OGNL and JSF EL, and evaluated or executed during the bean creation ti ...

  4. MVC架构和SSH框架对应关系

    MVC三层架构:模型层(model),控制层(controller)和视图层(view).模型层,用Hibernate框架让来JavaBean在数据库生成表及关联,通过对JavaBean的操作来对数据 ...

  5. VC 各种情况下的窗口句柄的获取

    动窗口的句柄.否则,返回值为NULL. GetSafeHwnd 函数功能:获取某个窗口对象(CWnd的派生对象)指针的句柄(HWND)时,最安全的方法是使用GetSafeHwnd()函数. 通过下面的 ...

  6. 通过 监听器获取sessionId

    package shopping; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpSess ...

  7. C#客户端链接网页需要用到的WebClient

    WebClient 类提供向 URI 标识的任何本地.Intranet 或 Internet 资源发送数据以及从这些资源接收数据的公共方法. WebClient 类使用 WebRequest 类提供对 ...

  8. 教你50招提升ASP.NET性能(十六):把问题仍给硬件而不是开发人员

    (27)Throw hardware at the problem, not developers 招数27: 把问题仍给硬件而不是开发人员 As developers, we often want ...

  9. Ping批量函数

    function pingm ($file){ $ips = gc $file foreach ($ip in $ips) { $cmdline +="ping " + $ip + ...

  10. 数据字符集mysql主从数据库,分库分表等笔记

    文章结束给大家来个程序员笑话:[M] 1.mysql的目录:在rpm或者yum安装时:/var/lib/mysql  在编译安装时默许目录:/usr/local/mysql 2.用rpm包安装的MyS ...