泛型:

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. F5 刷新功能

    //1.引入单元 uses ShlObj; //2.执行命令 procedure TForm1.Button1Click(Sender: TObject); begin SHChangeNotify( ...

  2. java 字符串String操作工具类

    /** * StrKit. */ public class StrKit { /** * 首字母变小写 */ public static String firstCharToLowerCase(Str ...

  3. JQuery学习使用笔记 -- JQuery插件开发

    内容转载自 http://www.css88.com/archives/4821 扩展jQuery插件和方法的作用是非常强大的,它可以节省大量开发时间.这篇文章将概述jQuery插件开发的基本知识,最 ...

  4. hibernate id生成器配置

    1.uuid配置 <id name="tomdId" type="java.lang.String"> <column name=" ...

  5. UVa442 Matrix Chain Multiplication

    // UVa442 Matrix Chain Multiplication // 题意:输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数.假定A和m*n的,B是n*p的,那么AB是m*p的,乘法 ...

  6. 配置文件struts2Struts2配置文件模块化包含(include)与action总结

    本文是一篇关于配置文件struts2的帖子 <include>标签 当Struts配置文件比较多,需要模块化分别或分开成为多个配置文件时,这个功能比较好. 则需要使用<include ...

  7. 【M2】最好使用C++转型操作符

    1.C语言中的转型操作符有两个问题: a.是个通用的转换操作符,也就是说,可以从一个类型转换到其他类型.通用必定是低效率和冗余的,因为要考虑很多情况. b.在代码中,难以辨认出哪些是类型转换. 2.C ...

  8. main方法执行之前,做什么事

    1.我们知道程序的入口是main方法,那么在执行main方法之前,需要做些什么准备工作呢? 2.main方法执行之前,必须要把non-local static对象构造完成.static对象有:全局对象 ...

  9. IOS 7 开发范例 - UISwitch的使用

    Creating and Using Switches with UISwitch You would like to give your users the ability to turn an o ...

  10. cocos2d-x 3.0环境搭建

    原文来自于:http://blog.csdn.net/linzhengqun/article/details/21663341 安装工具 1. 配置JDK JDK下载地址:http://www.ora ...