江南好,何处异京华。

香散翠帘多在水,绿残红叶胜于花。无事避风沙。

                              ——《纳兰词》

诗词再好,大图不能忘

上大图:

先说说栈和队列:

栈就好比手枪的弹匣,你往里面压入子弹,最先压入的子弹就到了弹匣最底部的位置,最后压入的子弹在弹匣顶部。发射子弹的时候每次将弹匣顶部的子弹弹出发射。无法越过顶部子弹发射下面的子弹。

栈(stack)是限定仅在表尾进行插入和删除操作的线性表,LIFO

队列就跟上学那会儿排队打饭一样,但是不能加塞儿。

队列(queue)是只允许在队列一端进行插入操作,另一端进行删除操作的线性表,FIFO

这里要特别说明Java中的队列是双向队列(Deque),包括了栈和队列的所有方法

双向队列也分为两种,顺序结构和链式结构。咱们看Deque接口实现类的名字就能看出来ArrayDeque是顺序存储结构,LinkedList是链式存储结构

基本原理就不再赘述了,第一篇已经讲过了顺序结构线性表和链式结构线性表。这里的栈和队列并不是什么新东西,只是两种不同的思维方式,对应了各自不同的方法罢了。

上代码:

 public class ArrayDequeStackDemo {

     public static void main(String[] args) {
ArrayDeque<String> stack = new ArrayDeque<>();
//以下均为栈操作,在逻辑上把队列想象成一个栈,FILO
stack.push("疯狂Java讲义");
stack.push("轻量级Java EE 企业应用实战");
stack.push("疯狂Android讲义");
//[疯狂Android讲义, 轻量级Java EE 企业应用实战, 疯狂Java讲义]
System.out.println(stack); //“窥视”栈顶第一个元素,而不出栈。输出:疯狂Android讲义
System.out.println(stack.peek());
//依然输出[疯狂Android讲义, 轻量级Java EE 企业应用实战, 疯狂Java讲义]
System.out.println(stack); //获取栈顶,并pop出栈。输出:疯狂Android讲义
System.out.println(stack.pop());
//[轻量级Java EE 企业应用实战, 疯狂Java讲义]
System.out.println(stack);
}
}
 public class ArrayDequeQueueDemo {

     public static void main(String[] args) {
ArrayDeque<String> queue = new ArrayDeque<>();
//以下均为队列操作,在逻辑上把队列想象成一个栈,FIFO
queue.offer("疯狂Java讲义");
queue.offer("轻量级Java EE 企业应用实战");
queue.offer("疯狂Android讲义");
//[疯狂Java讲义, 轻量级Java EE 企业应用实战, 疯狂Android讲义]
System.out.println(queue); //“窥视”栈顶第一个元素,而不出栈。输出:疯狂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);
}
}

队列和栈的操作基本上就是这些

再说说Set集合

Set集合就像一个袋子,里面装着若干元素,它们无序且不能重复。

HashSet是Set的实现类,HashSet中的元素无序且不可重复

上代码:

 public class HashSetTest {

     public static void main(String[] args) {
HashSet<Object> h = new HashSet<>();
h.add(new ClassA());//A类重写equals(Object o),return true
h.add(new ClassA());//equals相等,hashCode不等
h.add(new ClassB());//重写hashCode(),return 1
h.add(new ClassB());//hashCode相等,equals不等
h.add(new ClassC());//重写equals(Object o),return true;重写hashCode(),return 2;
h.add(new ClassC());//并没有添加成功,hashCode和equals都相等,这两个对象在HashSet中相等
h.add(new ClassC2());//new ClassC2类,重写代码和ClassC一样,一样添加不了.说明hashCode只比较@后面的hashCode值,和@前面的东西无关
System.out.println(h);
//只看包名后面的结果:ClassB@1,ClassB@1,ClassC@2,ClassA@15db9742,ClassA@6d06d69c
}
}
 public class ClassA {

     public boolean equals(Object o){
return true;
}
}
public class ClassB { public int hashCode(){
return ;
}
}
public class ClassC { public int hashCode(){
return ;
}
public boolean equals(Object o){
return true;
}
}
public class ClassC2 { public int hashCode(){
return ;
}
public boolean equals(Object o){
return true;
}
}

1、基础知识:HashSet判断连个元素相等的方法:hashCode值相等 && equals 为true。

HashSet集合里的元素都没有索引。当程序向HashSet中添加元素的时候,HashSet会根据该元素的hashCode值来计算它的存储位置。访问数据的时候HashSet先计算该元素的hashCode值,再到对应的位置取元素。

所以HashSet访问元素也是很快的。

2、使用HashSet时可能会重写hashCode方法,如果重写了equals方法或者hashCode方法可能会导致一些问题

上代码:

 import java.util.HashSet;
import java.util.Iterator; public class HashSetTest2 { public static void main(String[] args) {
HashSet<ClassR> h = new HashSet<>();
h.add(new ClassR());
h.add(new ClassR());
h.add(new ClassR());
h.add(new ClassR());
h.add(new ClassR());//是不能加入相同元素的
System.out.println(h);
h.remove(new ClassR());//可以这样删除
System.out.println(h);
Iterator<ClassR> it = h.iterator();
ClassR r = (ClassR)it.next(); //把第一个元素赋值给r
r.count = ;//将集合中元素ClassR(1)值变成2,这样就和ClassR(2)重复了,hashCode和equals都相等
System.out.println(h);
h.remove(new ClassR());//删除classR(2)
h.remove(new ClassR());//原来的1已经不是1了,现在集合中没有地址为ClassR(1)地址,值为1的元素,所以无法删除
System.out.println(h);//这里剩下的应该就是原来的ClassR(1)(现在count值变成了2)和ClassR(3)
System.out.println("h中是否包含count为2的对象?"+h.contains(new ClassR())
+ "\nh中是否包含count为1的对象?"+h.contains(new ClassR()));
}
}
 public class ClassR {

     int count;
public ClassR(int count){
this.count = count;
}
public String toString(){
return "R[count:"+count+"]";
}
public boolean equals(Object o){
if (this == o)
return true;
if (o != null && o.getClass() == ClassR.class) {
ClassR r = (ClassR)o;
return this.count == r.count;
}
return false;
}
public int hashCode(){
return this.count;
}
}

以上是重写hashCode和equals算法的例子,对比不重写hashCode和equals算法,代码用之前的把ClassR中的重写内容删除就行了。

如果不重写,那么new出来的对象都是不同的元素(至少表面上看是这样,遗憾的是hashCode算法是native方法,无需探知。这里假设元素不是很多的情况下hashCode不会重复),但是重写之后你会发现new出来的对象不仅hashCode会相等,甚至更改某对象属性(字段)后居然两个对象equals为true了。这将会导致HashSet无法准确访问该元素。

3、HashSet优点:HashSet可以自由增加自身长度,并且访问元素速度很快

4、HashSet有个子类叫LinkedHashSet.

LinkedHashSet继承了父类的算法和寻址方式,其新增功能是使用链表维护内部顺序。由于需要维护元素的插入顺序,LinkedHashSet性能略低于其父类HashSet,但是在迭代访问Set中全部元素时有很好的性能。

最后TreeSet是Set的另一个实现类,TreeSet中的元素是有序不可重复的。

1、自然排序

TreeSet会调用集合元素的compareTo(Object obj)方法比较元素之间的大小关系,然后将集合中元素按照升序排列,这就是自然排序

2、定制排序

可重写compareTo方法实现定制排序。

Set就说到这里吧。

Java学习笔记——浅谈数据结构与Java集合框架(第二篇、Queue、Set)的更多相关文章

  1. Java学习笔记——浅谈数据结构与Java集合框架(第一篇、List)

    横看成岭侧成峰,远近高低各不同.不识庐山真面目,只缘身在此山中. --苏轼 这一块儿学的是云里雾里,咱们先从简单的入手.逐渐的拨开迷雾见太阳.本次先做List集合的三个实现类的学习笔记 List特点: ...

  2. Java学习笔记——浅谈数据结构与Java集合框架(第三篇、Map)

    桃李春风一杯酒,江湖夜雨十年灯 --寄黄几复 之前图上写错了,是Hashtable类.t是小写的,它是个很古老的类,以至于命名都没有那么规范.. HashMap HashMap就是存储key-valu ...

  3. java设计模式学习笔记--浅谈设计模式

    设计模式的目的 编写软件的过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战.设计模式为了让程序具有更好的 1.代码重用性(即:相同功能的代码,不用多次编写) ...

  4. 疯狂Java学习笔记(84)----------大约 Java 对象序列化,你不知道 5 事

    几年前,.当一个软件团队一起用 Java 书面申请.我认识比一般程序猿多知道一点关于 Java 对象序列化的知识所带来的优点. 关于本系列 您认为自己懂 Java 编程?其实,大多数程序猿对于 Jav ...

  5. 疯狂Java学习笔记(70)-----------挚爱Java

    与大家分享! 挚爱Java 10个使用Java最广泛的现实领域 写好Java代码的30条经验总结 Java字符串的substring真的会引起内存泄露么? Java内存的原型及工作原理深度剖析 Jav ...

  6. Java学习笔记(十六)——Java RMI

    [前面的话] 最近过的好舒服,每天过的感觉很充实,一些生活和工作的技巧注意了就会发现,其实生活也是可以过的如此的有滋有味,满足现在的状况,并且感觉很幸福. 学习java RMI的原因是最近在使用dub ...

  7. 0031 Java学习笔记-梁勇著《Java语言程序设计-基础篇 第十版》英语单词

    第01章 计算机.程序和Java概述 CPU(Central Processing Unit) * 中央处理器 Control Unit * 控制单元 arithmetic/logic unit /ə ...

  8. Java学习笔记(十四)——Java静态工厂

    [前面的话] 每天过的还行,对我来说,只要让自己充实,生活就会是好的. 学习Java工场方法的原因是最近在使用Spring框架做一个系统,其中有一个注入的方法是使用静态工场方法注入,所以学习一下,基础 ...

  9. 零基础学Java之Java学习笔记(一):Java概述

    什么是Java? Java是一门面向对象编程语言,可以编写桌面应用程序.Web应用程序.分布式系统和嵌入式系统应用程序. Java特点有哪些? 1.Java语言吸收了C++语言的各种优点,具有功能强大 ...

随机推荐

  1. java与JSTL库

    JSTL1. jstl的概述  * apache的东西,依赖EL  * 使用jstl需要导入jstl1.2.jar  * 四大库:    > core:核心库,重点    > fmt:格式 ...

  2. ngrok完成内网映射外网

    项目需求: 完成微信公众号开发配置搭建,其中需要一个可以外部访问的域名 实现技术: www.ngrok.cc 实现方式: 在该网站最下方下载需要的ngrok文件,在最上方点击注册,获取token,之后 ...

  3. 手机自动化测试:appium源码分析之bootstrap四

    手机自动化测试:appium源码分析之bootstrap四   Orientation是调整屏幕方向的操作 package io.appium.android.bootstrap.handler; i ...

  4. AngularJS1.X学习笔记6-控制器和作用域

    经过一番艰苦卓绝的鏖战,我终于来到了控制器和作用域部分.控制器作为MVC的C,其重要性不可谓不重要:作用域决定了你可以拿到哪些东西,亦是分外重要.现在就来学习一下两个东西.去看看$apply,$wat ...

  5. 插入排序的优化非希尔【不靠谱地讲可以优化到O(nlogn)】 USACO 丑数

    首先我们先介绍一下普通的插排,就是我们现在一般写的那种,效率是O(n^2)的. 普通的插排基于的思想就是找位置,然后插入进去,其他在它后面的元素全部后移,下面是普通插排的代码: #include< ...

  6. js的apply()与call()的区别

    1.各自对应的不同的语法: /*apply()方法*/ function.apply(thisObj[, argArray]) /*call()方法*/ function.call(thisObj[, ...

  7. bit ( 比特 )和 Byte(字节)的关系 以及 网速怎么算

    今天来整理一下存储单位和网速的知识. 最近几天家里网不太好,所以就了解了一下网速和电脑的存储单位的关系. 一.存储单位的bit 和 Byte 1.bit(比特) bit也就是我们不一定听说过的比特,大 ...

  8. Oracle自动备份.bat 最新更新(支持Win10了)

    20170418更新: 很多年没有用了,最近两天打开来用,发现在Win10下面At命令已经被淘汰不能使用了,还有不少命令工作方式和原来也不一样了 所以就更新了一下下,使用 schtasks 命令代替了 ...

  9. ASP.NET MVC4 微信公众号开发之网页授权(一):搭建基础环境

    首先你得注册并认证一个个人或企业的微信公众号===服务号从而确保获得以下接口权限: 然后打开公众号设置里的功能设置里找到业务域名和网页授权域名分别填上你的域名(注:已备案的域名),如下图所示: 到这里 ...

  10. 想成为Java高级工程师的看过来

    想成为Java高级工程师,有哪些要求呢? 1.Core Java,就是Java基础.JDK的类库,很多童鞋都会说,JDK我懂,但是懂还不足够,知其然还要知其所以然,JDK的源代码写的非常好,要经常查看 ...