1.2版本的JDK才出现的java集合框架。

下面介绍说一下Vector的一些特点。

 1 import java.util.Enumeration;
 2 import java.util.Iterator;
 3 import java.util.Vector;
 4 public class VectorDemo {
 5     public static void main(String[] args) {
 6
 7         Vector v = new Vector();
 8         v.addElement("abc1");
 9         v.addElement("abc2");
10         v.addElement("abc3");
11         v.addElement("abc4");
12
13         Enumeration en = v.elements();
14         while(en.hasMoreElements()){
15             System.out.println("nextelment:"+en.nextElement());
16         }
17         Iterator it = v.iterator();
18         while(it.hasNext()){
19             System.out.println("next:"+it.next());
20         }
21     }
22 }

方法名上只要有Elements的都是Vector特有 的方法。

Vector中有一个elements()方法。

Enumeration<E>

elements()
          返回此向量的组件的枚举。

接口 Enumeration<E>

注:此接口的功能与 Iterator 接口的功能是重复的。此外,Iterator 接口添加了一个可选的移除操作,并使用较短的方法名。新的实现应该优先考虑使用 Iterator 接口而不是 Enumeration 接口。

从以下版本开始:

JDK1.0

Enumeration接口也是很早就出现的,但是现在基本上不用了,在jdk2.0之前都是使用该方法进行遍历的,那时候还没有Iterator接口。但是由于其名字比较长,而郁郁而终。

例如,要输出 Vector<E> v 的所有元素,可使用以下方法:

for (Enumeration<E> e = v.elements(); e.hasMoreElements();)System.out.println(e.nextElement());

上面是java API中的描述,重点是使用了for循环。

LinkedList

void

addFirst(E e)
          将指定元素插入此列表的开头。

void

addLast(E e)
          将指定元素添加到此列表的结尾。

E

getFirst()
          
返回此列表的第一个元素。

E

getLast()
          
返回此列表的最后一个元素。

E

remove()
          获取并移除此列表的头(第一个元素)。

E

remove(int index)
          移除此列表中指定位置处的元素。

LinkedList:

addFirst();

addLast():

jdk1.6

offerFirst();在此列表的开头插入指定的元素

offerLast();在此列表末尾插入指定的元素。

getFirst();.//获取但不移除,如果链表为空,抛出NoSuchElementException.

getLast();

jdk1.6

peekFirst();//获取但不移除,如果链表为空,返回null.

peekLast():

removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException.

removeLast();

jdk1.6

pollFirst();//获取并移除,如果链表为空,返回null.

pollLast();

自动装箱:基本数据类型转换成引用数据类型。

自动拆箱:引用数据类型和基本数据类型做运算的时候。

ArrayList集合存储自定对象:

Person.java

 1 public class Person {
 2     private String name;
 3     private int age;
 4     public String getName() {
 5         return name;
 6     }
 7     public void setName(String name) {
 8         this.name = name;
 9     }
10     public int getAge() {
11         return age;
12     }
13     public void setAge(int age) {
14         this.age = age;
15     }
16     public Person(String name, int age) {
17         super();
18         this.name = name;
19         this.age = age;
20     }
21 }

ArrayListTest.java

 1 import java.util.ArrayList;
 2 import java.util.Iterator;
 3 public class ArrayListTest {
 4     public static void main(String[] args) {
 5         ArrayList list = new ArrayList();
 6
 7         list.add(new Person("lisi1",11));
 8         list.add(new Person("lisi2",12));
 9         list.add(new Person("lisi3",13));
10         list.add(new Person("lisi4",14));
11
12         Iterator it =list.iterator();
13         while(it.hasNext()){
14             //System.out.println(((Person) it.next()).getName()+"--"+((Person) it.next()).getAge());         //输出://lisi1--12         //lisi3—-14   出现名字和姓名交错的现象原因就是next()访问完一个对象之后接着去访问下一个对象。
15             Person p = (Person) it.next();
16             System.out.println(p.getName()+"----"+p.getAge());
17         }
18     }
19 }

输出结果:

lisi1----11
lisi2----12
lisi3----13
lisi4----14

Set:元素不可以重复,是无序的。

Set接口中的方法和Collection一致。

|--HashSet: 内部数据结构是哈希表 ,是不同步的。

如何保证该集合的元素唯一性呢?

是通过对象的hashCode和equals方法来完成对象唯一性的。

如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。

如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。

如果为true,视为相同元素,不存储。如果为false,那么视为不同元素,就进行存储。

记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。

一般情况下,如果定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。

建立对象判断是否相同的依据。

哈希算法是底层windows做的,而且针对不同的对象有不同的哈希算法运算。

java类中有的哈希算法是native用的windows底层 的,有的根据对象的不同进行了重写。

哈希表:哈希这种算法会算出很多的值,把这些值存储起来形成一个表。表中有对应关系。

哈希表中还是数组。只是哈希这种算法对数组进行了优化。

哈希算法有一种最常见的算法就是取余。

哈希表中不能有重复的元素。

哈希表是如何判断元素是否是重复的?

“ab”和”ba”产生的哈希值是一样的,取余之后都是5,但是内容不一样,哈希值对这样的情况也有对应的方法,在5角标出“挂”一个”ba”。

在list集合remove和contains都要判断相不相同,都是用的equals、

如果到了set集合,要删除一个元素,要依据该元素是否和该容器中的元素是否相同。

hashset依据hashcode和equals。

用HashSet存储自定义对象

Person.java

 1 public class Person {
 2     private String name;
 3     private int age;
 4     public String getName() {
 5         return name;
 6     }
 7     public void setName(String name) {
 8         this.name = name;
 9     }
10     public int getAge() {
11         return age;
12     }
13     public void setAge(int age) {
14         this.age = age;
15     }
16     public Person(String name, int age) {
17         super();
18         this.name = name;
19         this.age = age;
20     }
21 }

HashSetTest.java

 1 import java.util.HashSet;
 2 import java.util.Iterator;
 3 public class HashSetTest {
 4     public static void main(String[] args) {
 5         HashSet set = new HashSet();
 6         set.add(new Person("lisi1",11));
 7         set.add(new Person("lisi2",12));
 8         set.add(new Person("lisi3",13));
 9         set.add(new Person("lisi4",14));
10         set.add(new Person("lisi4",14));
11         Iterator it = set.iterator();
12         while(it.hasNext()){
13             Person p = (Person) it.next();
14             System.out.println(p.getName()+"---"+p.getAge());
15         }
16     }
17 }

打印的结果是:

lisi3---13

lisi4---14

lisi1---11

lisi2---12

lisi4---14

集合中存储进去了两个“lisi4 14”又是集合Set ,Set集合中不会再存储相同的元素。为什么出现这种情况。

首先这是Set存储用户自定义对象。

其次Person类继承的是Object,每new一个Person都有不同的地址值,hashcode不同,对于Set集合来说是不同的元素。

第三你自己定义的只要名字和年龄一样就是不同的对象这个规则程序现在是不知道的。需要你自己去定义,完善。

修改之后的代码:

Person.java

 1 public class Person extends Object {
 2     private String name;
 3     private int age;
 4     public String getName() {
 5         return name;
 6     }
 7     public void setName(String name) {
 8         this.name = name;
 9     }
10     public int getAge() {
11         return age;
12     }
13     public void setAge(int age) {
14         this.age = age;
15     }
16     public Person(String name, int age) {
17         super();
18         this.name = name;
19         this.age = age;
20     }
21     //hashCode()方法返回的是一个int类型的值,这里根据Person类对象的特点,返回一个由name和age属性决定的值最合适。age之后乘以的数字只要不是1,都可以。
22     @Override
23     public int hashCode() {
24         System.out.println(this+".......hashCode");
25         return name.hashCode()+age*27;
26     }
27     @Override
28     public boolean equals(Object obj) {
29         if(this == obj)
30             return true;
31         if(!(obj instanceof Person))
32             throw new ClassCastException("类型错误");
33         System.out.println(this+"....equals....."+obj);
34         Person p = (Person)obj;
35         return this.name.equals(p.name) && this.age == p.age;
36     }
37     public String toString(){
38          return name +":"+ age;
39     }
40 }

从输出的结果可以看出来,这两句if语句并没有执行,因为如果执行了就不会再执行下面的语句了,if中的语句是return结束语句。我在debug模式下inspect监察if中的语句也都是false。

第二if语句感觉到确实是有用,第一句有什么用处呢?

第一if语句的用处就在于,当判断完hashCode()方法之后hash值相同,如果内容也相同,就用if(this ==obj),这样结束equals语句中的判断。

在写上面这段代码时候,我没有重写toString方法,程序就会报错。

Exception in thread "main" java.lang.StackOverflowError

at java.lang.Object.toString(Unknown Source)

at java.lang.String.valueOf(Unknown Source)

at java.lang.StringBuilder.append(Unknown Source)

at Mypack.Person.hashCode(Person.java:26)

如果不重写此方法打印的就是对象,如果不重写toString就是打印的hashcode值,但是这里重写了hashCode方法。

HashSetTest.java

 1 import java.util.HashSet;
 2 import java.util.Iterator;
 3 public class HashSetTest {
 4     public static void main(String[] args) {
 5         HashSet set = new HashSet();
 6         set.add(new Person("lisi1",11));
 7         set.add(new Person("lisi2",12));
 8         set.add(new Person("lisi3",13));
 9         set.add(new Person("lisi4",14));
10         set.add(new Person("lisi4",14));
11         Iterator it = set.iterator();
12         while(it.hasNext()){
13             Person p = (Person) it.next();
14             //System.out.println(p);
15             System.out.println(p.getName()+"---"+p.getAge());
16         }
17     }
18 }

输出:

lisi1:11.......hashCode

lisi2:12.......hashCode

lisi3:13.......hashCode

lisi4:14.......hashCode

lisi4:14.......hashCode

lisi4:14....equals.....lisi4:14

lisi2---12

lisi1---11

lisi4---14

lisi3---13

从上面的输出可以看出在初始化Set集合的时候调用了hashCode()方法,在初始化第二个lishi4的时候set就对其中的元素进行了check,用到了equals方法。

System.out.println(age.hashCode());

System.out.println(name.hashCode());

当时很纳闷name作为一个类中的属性,怎么能有hashCode()方法呢?hashCode()方法不是对象才所具有的吗?于是我就尝试打印age的哈希值,报这个错误:Cannot invoke hashCode() on the primitive type int。

hashCode()确实只有对象才有,但是age是个int类型的,name是String类型的,String类型是对象类型。所以name属性有hashCode()方法。

/*

* 定义功能去除ArrayList中的重复元素。

*/

Person.java

 1 public class Person extends Object {
 2     private String name;
 3     private int age;
 4     public String getName() {
 5         return name;
 6     }
 7     public void setName(String name) {
 8         this.name = name;
 9     }
10     public int getAge() {
11         return age;
12     }
13     public void setAge(int age) {
14         this.age = age;
15     }
16     public Person(String name, int age) {
17         super();
18         this.name = name;
19         this.age = age;
20     }
21     public String toString(){
22         return name +":"+ age;
23     }
24
25     @Override
26     public boolean equals(Object obj) {
27
28         if(this == obj)
29             return true;
30         if(!(obj instanceof Person))
31             throw new ClassCastException("类型错误");
32         Person p = (Person)obj;
33         return this.name.equals(p.name) && this.age == p.age;
34     }
35 }

ArrayList中判断元素是否存在就只重写了一个equals()方法。

用equals()方法来判断对象的属性值是否都相同。

ArrayListTest2 .java

 1 public class ArrayListTest2 {
 2     public static void main(String[] args) {
 3         ArrayList al = new ArrayList();
 4         al.add(new Person("lisi1",21));
 5         al.add(new Person("lisi2",22));
 6         al.add(new Person("lisi3",23));
 7         al.add(new Person("lisi4",24));
 8         al.add(new Person("lisi2",22));
 9         al.add(new Person("lisi3",23));
10
11         System.out.println(al);
12         al = getSingleElement(al);
13
14         System.out.println(al.remove(new Person("lisi2",22))); //返回值是true      //虽然这个地方new的是一个新对象,但是remove还是把arraylist中的以有该数据删除,因为关键的地方是contains中判断的就是equals,      //equals两个数据内容相同则视为同一个元素,remove返回的是boolean。
15         System.out.println(al);
16     }
17     public static ArrayList getSingleElement(ArrayList list) {
18         ArrayList temp = new ArrayList();
19         Iterator it = list.iterator();
20         while(it.hasNext()){
21             Object obj = it.next();
22             //判断被迭代到的元素是否在临时容器中存在
23             if(!temp.contains(obj)){
24                 temp.add(obj);
25             }
26         }
27         return temp;
28     }
29 }

输出:  

[lisi1:21, lisi2:22, lisi3:23, lisi4:24, lisi2:22, lisi3:23]
true
[lisi1:21, lisi3:23, lisi4:24]

LinkedHashSet

HashSet是无序的,但是其下的小弟是有有序功能的,就是LinkedHashSet。

具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。

保证唯一还要有序就直接用LinkedHashSet.就可以实现。

HashSet hs = new LinkedHashSet();

|--TreeSet:可以对Set集合中的元素进行排序。是不同步的,即是线程不安全的。

判断元素唯一性的方式:就是根据比较方法compareTo()的返回结果是否是0,是0,就是相同元素,不存。

集合中判断元素不同的方式???

Set中其他的都根据hashcode和equals方法。

TreeSet对元素进行排序的方式一:

让元素自身具备比较功能,就需要实现Comparable接口。覆盖compareTo方法。

如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?

可以使用TreeSet集合第二种排序方式二:

让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。

将该类对象作为参数传递给TreeSet集合的构造函数。

TreeSet是排序用的,有排序就需要比较。

public interface Comparable<T>

此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法

compareTo

int compareTo(T o)

比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

只要对象需要比较就要实现这个接口。

字符串String 本身就实现了Comparable接口,可以直接进行排序。

 1 public int compareTo(Object o) {
 2
 3         Person p = (Person)o;
 4
 5         int  temp = this.age-p.age;
 6         return temp==0?this.name.compareTo(p.name):temp;
 7
 8
 9
10         int  temp = this.name.compareTo(p.name);
11         return temp==0?this.age-p.age:temp;
12     }

集合自身具有比较性,具有两个才能比。而元素自身具有比较性传一个就能比,元素自身是一个对象。

TreeSet(Comparator<? super E> comparator)

构造一个新的空 TreeSet,它根据指定比较器进行排序。

接口 Comparator<T>

 int

compare(T o1, T o2)
          比较用来排序的两个参数。

compare

int compare(T o1,T o2)

比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。

TreeSet具备比较器,Person具备自然排序,进行元素比较时以TreeSet为主。开发中也是。

java中的很多类都实现了Comparable接口。String,Integer。

凡是一个类具备n多对象的,基本上都实现了这个接口,让其具备比较性。

这个是类的默认比较方式。如果想指定的话最好使用比较器进行。

TreeSetDemo.java

TreeSet ts = new TreeSet(new ComparatorByName());

让TreeSet集合对象在一开始初始化的时候就具备一个比较器。

ComparatorByName.java

姓名比较器的具体实现:

 1 import java.util.Comparator;
 2 /**
 3  * 创建了一个根据Person类的name进行排序的比较器。
 4  */
 5 public class ComparatorByName implements Comparator {
 6
 7     @Override
 8     public int compare(Object o1, Object o2) {
 9         Person p1 = (Person)o1;
10         Person p2 = (Person)o2;
11
12         int temp = p1.getName().compareTo(p2.getName());
13
14         return temp==0?p1.getAge()-p2.getAge(): temp;
15     }
16 }

根据字符串的长度设置比较器。

ComparatorByLength.java

 1 public class ComparatorByLength implements Comparator {
 2     @Override
 3     public int compare(Object o1, Object o2) {
 4         String s1 = (String)o1;
 5         String s2 = (String)o2;
 6
 7         int temp = s1.length()-s2.length();
 8
 9         return temp==0? s1.compareTo(s2): temp;
10     }
11 }

if(this.hashCode()== obj.hashCode() && this.equals(obj))

哈希表确定元素是否相同

1,判断的是两个元素的哈希值是否相同。

如果相同,在判断两个对象的内容是否相同。

2,判断哈希值相同,其实判断的是对象的hashCode的方法。判断内容相同,用的是equals方法。

注意:如果哈希值不同,是不需要判断equals。

关于JDK中的集合总结(二)相关推荐

  1. 在java中重写方法应遵循规则的包括_Java面试题集合篇二

    Java面试题之Java集合篇二1.遍历一个List有哪些不同的方式? List<String> strList = new ArrayList<>(); //使用for-ea ...

  2. JDK 中的 BIO 实现原理分析(二十)

    今天对JDK 中的 BIO 实现原理进行分析 一.简介 对比 Linux 上网络编程,我们会发现 JDK Socket 的编程逻辑是一模一样的.实际上也是这样,JDK 网络编程也没有做很多事,主要还是 ...

  3. 万字长文深入理解java中的集合-附PDF下载

    文章目录 1. 前言 2. List 2.1 fail-safe fail-fast知多少 2.1.1 Fail-fast Iterator 2.1.2 Fail-fast 的原理 2.1.3 Fai ...

  4. 从JDK中,我们能学到哪些设计模式?

    作者:肥朝  来自:肥朝(ID:feichao_java) 结构性模式: 适配器模式: 常用于将一个新接口适配旧接口 肥朝小声逼逼:在我们业务代码中经常有新旧接口适配需求,可以采用该模式. 桥接模式: ...

  5. 观察者模式--java jdk中提供的支持

    一.简介 观察者设计模式有如下四个角色 抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者.抽象主题提供一个接口,可以增加和删除观察者角色.一般用一个抽象 ...

  6. Java中Set集合的使用和底层原理

    文章目录 Set系列集合介绍 Set集合概述 HashSet无序原理 Set集合对象去重 LinkedHashSet TreeSet排序规则 Set系列集合介绍 Set集合概述 Set系列集合特点: ...

  7. Java中List集合介绍(炒鸡详细呦)

    Java中List集合介绍 文章目录 Java中List集合介绍 1,Java集合介绍 2,List介绍 2.1 ArrayList集合 2.2 LinkedList集合 3,List常用方法 3.1 ...

  8. 那些jdk中坑你没商量的方法

    点击关注公众号,Java干货及时送达 来源:https://www.cnblogs.com/wyq178/p/13520745.html 前言 jdk作为我们每天必备的调用类库,里面大量提供了基础类供 ...

  9. JDK中的坑:JDK中这些方法的bug你不要踩

    点击关注公众号,Java干货及时送达 图片来源:白夜追凶 前言: jdk作为我们每天必备的调用类库,里面大量提供了基础类供我们使用.可以说离开jdk,我们的java代码寸步难行,jdk带给我们的便利可 ...

最新文章

  1. MFC中的资源视图和如何打开资源视图
  2. 不懂技术的人不要对懂技术的人说这很容易实现
  3. Netty 4.x Netty 实现聊天功能
  4. 解决Eclipse、Android Studio ADT AVD不能检测到手机
  5. 写博客和生产api的工具
  6. 【超人】社区二手小程序v6.15.2+前端
  7. Android对话框动态加载布局
  8. 设置,获取和删除Cookies
  9. utilities——C++常用仿函数(二)
  10. 模型调参(AutoML)— optuna
  11. Windows下安装dilb解决方法
  12. 字模C语言入门,PCtoLCD2002完美版取字模工具软件及其步骤教程
  13. 英雄无敌3 Def 文件对应生物列表
  14. Word删除页眉横线的方法
  15. 企业宣传软文怎么写?手把手教大家撰写企业宣传软文
  16. QCMS企业建站系统 v5.0.1
  17. n的阶乘(递归与非递归)
  18. MongoDB4.4版本源码部署分片集群
  19. java程序怎么写_java程序怎么写
  20. 花园多层住宅设计CAD施工图教程分享

热门文章

  1. 怎么证明自己会python_1024程序员节,请用一句话证明你是一个程序员!
  2. 连接MySQL错误:Can't connect to MySQL server (10060)
  3. Java 读取Oracle数据库中的Date日期型怎么去掉秒后面的0
  4. oracle 判断非空字段
  5. ubuntu内网环境安装zabbix agent
  6. 百度App网络深度优化系列(一):DNS优化
  7. swift中没有selectall的解决
  8. fiddler启用过滤规则只显示想要的接口数据
  9. [译] 构建流畅的交互界面
  10. linux引导过程和服务控制