链表LinkedList

LinkedList 也像 ArrayList 一样实现了基本的 List 接口,但它在 List 中间执行插入和删除操作时比 ArrayList 更高效。然而,它在随机访问操作效率方面却要逊色一些。
LinkedList 还添加了一些方法,使其可以被用作栈、队列或双端队列(deque) 。在这些方法中,有些彼此之间可能只是名称有些差异,或者只存在些许差异,以使得这些名字在特定用法的上下文环境中更加适用(特别是在 Queue 中)。例如:

  • getFirst() 和 element() 是相同的,它们都返回列表的头部(第一个元素)而并不删除它,如果 List 为空,则抛出 NoSuchElementException 异常。 peek() 方法与这两个方法只是稍有差异,它在列表为空时返回 null 。
  • removeFirst() 和 remove() 也是相同的,它们删除并返回列表的头部元素,并在列表为空时抛出 NoSuchElementException 异常。 poll() 稍有差异,它在列表为空时返回 null 。
  • addFirst() 在列表的开头插入一个元素。
  • offer() 与 add() 和 addLast() 相同。 它们都在列表的尾部(末尾)添加一个元素。
  • removeLast() 删除并返回列表的最后一个元素。
/**
* @author myf
*/
public class LinkedListFeatures {
public static void main(String[] args) {
LinkedList<Fruits> fruitsList = new LinkedList<>();
LinkedList<Fruits> nullList = new LinkedList<>();
fruitsList.add(new Fruits("test"));
fruitsList.add(new Fruits("apple"));
fruitsList.add(new Fruits("orange"));
fruitsList.add(new Fruits("banana")); // NoSuchElementException
// System.out.println(nullList.getFirst());
// System.out.println(nullList.element());
// null
System.out.println(nullList.peek());
// Fruits{name='test'}
System.out.println(fruitsList.getFirst());
// Fruits{name='test'}
System.out.println(fruitsList.element());
// Fruits{name='test'}
System.out.println(fruitsList.peek()); // NoSuchElementException
// System.out.println(nullList.removeFirst());
// System.out.println(nullList.remove());
// null
System.out.println(nullList.poll());
// Fruits{name='test'}
System.out.println(fruitsList.removeFirst());
// Fruits{name='apple'}
System.out.println(fruitsList.remove());
// Fruits{name='orange'}
System.out.println(fruitsList.poll()); // [Fruits{name='banana'}]
System.out.println(fruitsList.toString());
fruitsList.addFirst(new Fruits("apple"));
// [Fruits{name='apple'}, Fruits{name='banana'}]
System.out.println(fruitsList.toString());
fruitsList.offer(new Fruits("test1"));
fruitsList.add(new Fruits("test2"));
fruitsList.addLast(new Fruits("test3"));
// [Fruits{name='apple'}, Fruits{name='banana'}, Fruits{name='test1'}, Fruits{name='test2'}, Fruits{name='test3'}]
System.out.println(fruitsList.toString()); fruitsList.removeLast();
// [Fruits{name='apple'}, Fruits{name='banana'}, Fruits{name='test1'}, Fruits{name='test2'}]
System.out.println(fruitsList);
}
}

堆栈Stack

堆栈是“后进先出”(LIFO)集合。它有时被称为叠加栈(pushdown stack),因为最后“压入”(push)栈的元素,第一个被“弹出”(pop)栈。经常用来类比栈的事物是带有弹簧支架的自助餐厅托盘。最后装入的托盘总是最先拿出来使用的。

Java 1.0 中附带了一个 Stack 类,结果设计得很糟糕(为了向后兼容,我们永远坚持 Java 中的旧设计错误)。Java 6 添加了 ArrayDeque ,其中包含直接实现堆栈功能的方法:

/**
* @author myf
*/
public class StackTest {
public static void main(String[] args) {
Deque<String> stringDeque = new ArrayDeque<>();
for (String s:"My dog has fleas".split(" ")){
stringDeque.add(s);
}
while (!stringDeque.isEmpty()){
System.out.println(stringDeque.pop());
}
}
}

即使我们是在实现一个堆栈,但我们仍必须将其声明为 Deque 。非常容易造成混淆。
我们可以写一个自己的Stack

/**
* @author myf
*/
public class Stack<T> {
private Deque<T> deque = new ArrayDeque<>();
public void push(T t){
deque.push(t);
} public T peek(){
return deque.peek();
} public T pop(){
return deque.pop();
} public boolean isEmpty(){
return deque.isEmpty();
} @Override
public String toString() {
return deque.toString();
}
}

这样我们在使用堆栈Stack时就可以使用我们自定义命名的这个堆栈了。

这里引入了使用泛型的类定义的最简单的可能示例。类名称后面的 告诉编译器这是一个参数化类型,而其中的类型参数 T 会在使用类时被实际类型替换。基本上,这个类是在声明“我们在定义一个可以持有 T 类型对象的 Stack 。” Stack 是使用 ArrayDeque 实现的,而 ArrayDeque 也被告知它将持有 T 类型对象。注意, push() 接受类型为 T 的对象,而 peek() 和 pop() 返回类型为 T 的对象。 peek() 方法将返回栈顶元素,但并不将其从栈顶删除,而 pop() 删除并返回顶部元素。

集合Set

Set 不保存重复的元素。 如果试图将相同对象的多个实例添加到 Set 中,那么它会阻止这种重复行为。 Set 最常见的用途是测试归属性,可以很轻松地询问某个对象是否在一个 Set 中。因此,查找通常是 Set 最重要的操作,因此通常会选择 HashSet 实现,该实现针对快速查找进行了优化。
Set 具有与 Collection 相同的接口,因此没有任何额外的功能,不像前面两种不同类型的 List 那样。实际上, Set 就是一个 Collection ,只是行为不同。(这是继承和多态思想的典型应用:表现不同的行为。)Set 根据对象的“值”确定归属性。

下面是使用存放 Integer 对象的 HashSet 的示例:

/**
* @author myf
*/
public class SetOfInteger {
public static void main(String[] args) {
Random rand = new Random(47);
Set<Integer> intset = new HashSet<>();
for(int i = 0; i < 10000; i++){
intset.add(rand.nextInt(30));
}
System.out.println(intset);
}
}
/* Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
*/

在 0 到 29 之间的 10000 个随机整数被添加到 Set 中,因此可以想象每个值都重复了很多次。但是从结果中可以看到,每一个数只有一个实例出现在结果中。

早期 Java 版本中的 HashSet 产生的输出没有可辨别的顺序。这是因为出于对速度的追求, HashSet 使用了散列,由 HashSet 维护的顺序与 TreeSet 或 LinkedHashSet 不同,因为它们的实现具有不同的元素存储方式。 TreeSet 将元素存储在红-黑树数据结构中,而 HashSet 使用散列函数。 LinkedHashSet 因为查询速度的原因也使用了散列,但是看起来使用了链表来维护元素的插入顺序。看起来散列算法好像已经改变了,现在 Integer 按顺序排序。但是,您不应该依赖此行为:

/**
* @author myf
*/
public class SetOfString {
public static void main(String[] args) {
Set<String> colors = new HashSet<>();
for(int i = 0; i < 100; i++) {
colors.add("Yellow");
colors.add("Blue");
colors.add("Red");
colors.add("Red");
colors.add("Orange");
colors.add("Yellow");
colors.add("Blue");
colors.add("Purple");
}
System.out.println(colors);
/* Output:
[Red, Yellow, Blue, Purple, Orange]
*/ Set<String> colors2 = new TreeSet<>();
for(int i = 0; i < 100; i++) {
colors2.add("Yellow");
colors2.add("Blue");
colors2.add("Red");
colors2.add("Red");
colors2.add("Orange");
colors2.add("Yellow");
colors2.add("Blue");
colors2.add("Purple");
}
System.out.println(colors2);
/* Output:
[Blue, Orange, Purple, Red, Yellow]
*/
// true
System.out.println(colors.contains("Yellow"));
}
}

HashSet,String 对象似乎没有排序。要对结果进行排序,一种方法是使用 TreeSet 而不是 HashSet 。
最常见的操作之一是使用 contains() 测试成员归属性

链表LinkedList、堆栈Stack、集合Set的更多相关文章

  1. 《Java数据结构与算法》笔记-CH5-链表-4用链表实现堆栈

    //用链表实现堆栈 /** * 节点类 */ class LinkS { private long data; public LinkS next; public LinkS(long d) { th ...

  2. C# 队列(Queue) 和堆栈(Stack)

    队列 (Queue)                                                                                          ...

  3. 用LinkedList模拟Stack功能

    集合体系在Java中比较重要,整个集合体系是在JDK1.2版本后出现,Collection作为整个体系的顶层,拥有整个体系通用的功能.对于其下面的小弟,也是各有千秋.下面就一道面试题来看看Linked ...

  4. java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)

    (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...

  5. java中堆栈(stack)和堆(heap)

    原文地址:http://blog.csdn.net/jerryao/article/details/874101 1.内存分配策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈 ...

  6. 集合、ArrayList 集合。Stack集合。Queue集合。以及Hashtable集合

    arrayList 首先复制Colections加  : 创建arrayList ar =new arrayList(); //ArrayList al=new ArrayList();        ...

  7. 3.2 java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)

    (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...

  8. Stack集合 Queue队列集合 Hashtable哈希表

    Stack集合 干草堆集合 栈集合 栈;stack,先进后出,一个一个赋值,一个一个取值,安装顺序来. 属性和方法 实例化 初始化 Stack st = new Stack(); 添加元素 个数 Co ...

  9. Stack集合、queue集合、hashtable集合

    1.栈:Stack,先进后出,一个一个赋值,一个一个取值,按顺序. .count           取集合内元素的个数 .push()         将元素一个一个推入集合中//stack集合存入 ...

随机推荐

  1. java课堂考试总结

    9月22日,进行了开学第一堂的java测试,来检验暑假的自学成果.下午的考试中,时间应该是比较充分的,但是我还是有许多功能模块没有完成,功能缺少,在进行测试的时候暴露出了许多漏洞. 总结一下,在暑假的 ...

  2. Windows内核开发-3-内核编程基础

    Windows内核开发-3-内核编程基础 这里会深入讲解kernel内核的API.结构体.和一些定义.考察代码在内核驱动中运行的机制.最后把所有知识合在一起写一个有用的驱动. 本章学习要点: 1:通用 ...

  3. Selnium + POM + Pytest:学习记录

    简介 selenium POM Pytest 结合,通过Pytest fixture 来传递Driver 保证一个测试用例[1] :driver[1] 学习记录 插件包 selenium: 操作浏览器 ...

  4. 每天五分钟Go - 循环语句

    带条件的for循环 for init; condition; post { } 示例代码 for i:=0;i<10;i++{ fmt.Println("current:", ...

  5. 【C#】C#中使用GDAL3(一):Windows下超详细编译C#版GDAL3.3.0(VS2015+.NET 4+32位/64位)

    转载请注明原文地址:https://www.cnblogs.com/litou/p/15004877.html 目录 一.介绍 二.编译准备 三.编译SQLite 四.编译LibTiff 五.编译PR ...

  6. odoo12里定时任务

    以odoo12为例: 1. 定义定时任务属性 <record id="ir_cron_submit_auto_action" model="ir.cron" ...

  7. JavaScript之DOM、DOM树

    一 DOM JavaScript操作网页的接口,全称为"文档对象模型"(Document Object Model). 有这几个概念:文档.元素.节点 整个文档是一个文档节点 每个 ...

  8. (opencv10)膨胀和侵蚀(Dilation与Erosion)

    (opencv10)膨胀和侵蚀(Dilation与Erosion) 图像形态学操作 图像形态学操作-基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学 形态学有四个基本操作:腐蚀, ...

  9. jvm源码解读--16 锁_开头

    现在不太清楚, public static void main(String[] args) { Object object=new Object(); System.out.println(&quo ...

  10. Unity3D学习笔记3——Unity Shader的初步使用

    目录 1. 概述 2. 详论 2.1. 创建材质 2.2. 着色器 2.2.1. 名称 2.2.2. 属性 2.2.3. SubShader 2.2.3.1. 标签(Tags) 2.2.3.2. 渲染 ...