zoukankan      html  css  js  c++  java
  • 集合(上)

    1、数据,指能够输入计算机中,由计算机所处理的元素。结构, 指数据之间的关系。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。

    常用的数据结构有:
    链表
    堆栈
    队列

    哈希表
    说明:堆栈、队列、链表为线性存储结构(线性表),即多个元素的有序序列。堆栈,队列为操作受限的线性表。 

    2、链表:链表存储的数据元素称为结点,在链表中,各个结点是有序的。
    每个结点分为两个部分:
    数据域
    指针域

    根据链表指针域的数量,可以将链表分为:
    单向链表
    双向链表

    单向链表:

    双向链表:前一个指向上一个结点,中间是数据域,后一个指向下一个结点。(循环双向链表)

    数组与链表的不同:

          存储方式:  数组在内存中时连续存储,链表在内存中不是连续存储。

    3、堆栈
    堆栈(简称栈)是一种操作受限的线性表,只能在表头增加或删除元素。我们通常将栈使用竖直的方式来表示,因此,表尾称为“栈顶”,表头称为“栈底”。栈表现的特征为后进先出。( LIFO) 

    4、队列
    队列是一种操作受限的线性表。只能在队尾增加元素,在队头删除元素。
    队列表现的特征为先进先出(FIFO)。
    队列分为:单端队列、双端队列
    当队列的两端都可以增加与删除元素时,这种队列称为双端队列。双端队列可以同时实现队列与堆栈的特征。

    5、树

    树是由结点集及连接每对结点的有向边集组成。

    如果存在有向边连接A到B,则A为B的父节点(父亲),B为A的子节点(孩子)。没有父节点的结点称为根,没有子节点的结点称为叶子。具有相同父节点的各结点称为兄弟。

    从根到某一节点经过的边数称为路径长度。

    6、二叉树

    二叉树是一种树形结构,其特征是任意结点的孩子数不超过两个。一棵二叉树要么为空,要么由根、左子树与右子树组成(左右子树可能为空)。

    一棵深度(树的层数)为m,且具有2m-1个结点的二叉树称为满二叉树。

    当一棵二叉树的所有结点编号(从上到下,从左到右进行)都与满二叉树一致时,该二叉树称为完全二叉树。

    7、树的遍历

    分为三种:先序遍历、中序遍历、后序遍历

    先序:先根》左子树》右子树

    中序:左子树》根》右子树

    后序:左子树》右子树》根

    8、哈希表
    将一组关键字映射到一个有限的地址集上,这种表称为哈希(散列)表。哈希表中,关键字映射到相应的地址需要使用相关的算法,称为哈希函数。关键字映射后所得的存储地址称为哈希(散列)地址。

    9、集合

    集合就是一系列元素的整体。

    集合就像是一个容器,可以存放与获取元素,与数组相似。不同的是,集合提供了很多有用的方法,用来操作与管理集合内的元素,而数组提供的方法很有限。

    集合和数组对比:

    缺点:集合的实现比数组更加复杂,因此,其性能上不如数组。

    优点:

    集合时不定长的,底层可以根据需要实现自动的扩容。而数组是定长的,我们在创建数组的时候就需要指定数组的长度。

    集合提供了很多有用的方法,可以操作集合内的元素,而数组提供的功能相对有限。

    10、集合框架

    11、集合分类:

        Collection接口提供元素存储。

        Map接口提供映射存储(键值对)

    package day14;
    /*
     * 集合
     * 集合与数组类型,类比一个容器,可以向里面加入元素。
     * 集合与数组的对比:
     * 缺点:集合的实现比数组更加复杂,因此,其性能上不如数组。
     * 优点:
     * 1 集合是不定长的,底层可以根据需要实现自动的扩容。
     * 而数组是定长的,我们在创建数组的时候就需要指定数组的长度。
     * 2 集合提供了很多有用的方法,可以操作集合内的元素,而数组
     * 提供的功能相对有限。
     */
    public class CollectionTest {
    	public static void main(String[] args) {
    
    	}
    }

    12、

    Collection 最基本的集合接口。用来存储一系列元素。
    Set继承Collection接口,不含有重复元素。
    List 继承Collection接口,List是有序集合,能精确控制每个元素插入的位置,可使用索引来访问List中的元素。
    Queue继承Collection接口。通常实现先进先出(FIFO)的规则,但这不是必须的。删除(获取)元素时,会获取队列头部的元素。先进先出的队列中,增加元素会追加到队列的末尾。
    Deque继承Queue接口。可同时在队列的两端增加与删除元素。
    Map接口提供key(键)到value(值)的映射,是一组成对的键-值对象。一个Map中不能有相同的key,每个key只能映射一个value。
    SortedSet继承Set接口,内部元素按照升序排列。
    SortedMap继承Map接口,key按照升序排列。

    13、collection常用方法

    package day14;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    public class CollectionMethod {
    	public static void main(String[] args) {
    		Collection<Integer> c = new ArrayList<>();
    		for (int i = 0; i < 10; i++) {
    			c.add(i);
    		}
    		// 返回集合中元素的个数。
    		System.out.println(c.size());
    		// 判断集合是否为空(集合元素个数是否为0),为空
    		// 返回true,否则返回false。
    		System.out.println(c.isEmpty());
    		// 判断集合中是否含有参数指定的元素(根据元素的equals方法)。
    		// 有返回true,否则返回false。
    		System.out.println(c.contains(5));
    		// 返回集合的迭代器,可以用来遍历集合每一个元素。
    		Iterator<Integer> iter = c.iterator();
    		// 将集合转换成数组,数组中的元素就是之前集合中的元素。
    		// 返回Object[]类型。
    		Object[] o = c.toArray();
    		Integer[] inte = new Integer[c.size()];
    		Integer[] i = c.toArray(inte);
    		// 向集合中加入参数指定的元素。如果当前集合发生改变,
    		// 返回true,否则返回false。
    		c.add(11);
    		// 删除集合中参数指定的元素。如果当前集合发生改变,
    		// 返回true,否则返回false。
    		c.remove(1);
    		Collection<Integer> c2 = new ArrayList<>();
    		c2.add(5);
    		c2.add(100);
    		// 判断当前集合是否包含参数指定集合中所有的元素。是
    		// 则返回true,否则返回false。
    		System.out.println(c.containsAll(c2));
    		// 将参数集合中所有的元素加入到当前集合中。如果当前集合
    		// 发生改变,返回true,否则返回false。
    		System.out.println(c.addAll(c2));
    		// 删除当前集合中存在,并且参数集合中也存在的所有元素。
    		// 如果当前集合发生改变,返回true,否则返回false。
    		System.out.println(c.removeAll(c2));
    		// 删除满足条件的所有元素。
    		c.removeIf(t -> t > 5);
    		System.out.println(c);
    		Collection<Integer> c3 = new ArrayList<>();
    		c3.add(100);
    		c3.add(101);
    		Collection<Integer> c4 = new ArrayList<>();
    		c4.add(100);
    		c4.add(102);
    		// 保留当前集合中存在,并且参数集合中也存在的所有元素。
    		// 即删除所有当前集合中存在,参数集合中不存在的所有元素。
    		// 如果当前集合发生改变,返回true,否则返回false。
    		c3.retainAll(c4);
    		System.out.println(c3);
    		// 删除集合中所有的元素。
    		c3.clear();
    
    	}
    }
    

      14、遍历集合方式

    可以使用以下方式来遍历集合:
     使用iterator接口。(原始方法)
     使用iterator接口。(新增方法)
     使用增强型for循环。
     使用forEach方法。
     使用聚合操作。
    

      

    package day14;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    import org.omg.Messaging.SyncScopeHelper;
    
    public class Tranverse {
    
    	public static void main(String[] args) {
    		Collection<Integer> c = new ArrayList<>();
    		for (int i = 0; i < 5; i++) {
    			c.add(i);
    		}
    		/*
    		 * 1 使用Iterator迭代器(原始的方法)
    		 */
    		// 返回集合的迭代器,迭代器的指针初始指向第一个元素之前。
    		Iterator<Integer> iter = c.iterator();
    		// 判断是否还有下一个元素,如果存在下一个元素,返回true,
    		// 否则返回false。
    		while (iter.hasNext()) {
    			// 获取下一个元素。同时移动当前的指针,指向当前
    			// 返回的元素。
    			Integer integer = iter.next();
    			System.out.println(integer);
    			// System.out.println(iter.next());
    			// 使用迭代器迭代的过程中,不能通过集合引用
    			// 删除元素,否则会产生ConcurrentModificationException异常。
    			// c.remove(0);
    			// 如果要在迭代的过程中删除元素,可以调用迭代器的
    			// remove方法。该方法会删除最后一次调用next
    			// 返回的元素。
    			// iter.remove();
    		}
    		/*
    		 * 2 使用Iterator接口迭代器(JDK1.8新增的方法)
    		 */
    		Iterator<Integer> iter2 = c.iterator();
    		// 对每一个剩下的元素(当前迭代器
    		// 指针之后的元素)执行指定的操作。
    		iter2.forEachRemaining(t -> System.out.println(t));
    		// 使用方法引用
    		iter2.forEachRemaining(System.out::println);
    		/*
    		 * 3 使用增强型for循环遍历
    		 */
    		for (Integer i : c) {
    			System.out.println(i);
    		}
    		/*
    		 * 4 使用集合类的forEach方法。
    		 */
    		c.forEach(t -> System.out.println(t));
    		c.forEach(System.out::println);
    		/*
    		 * 5 使用聚合操作
    		 */
    		c.stream().forEach(System.out::println);
    	}
    
    }
    

      15、List接口的方法

    /*
     * List接口的方法
     */
    package day14;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.ListIterator;
    
    public class ListMethod {
    	public static void main(String[] args) {
    		List<Integer> list = new ArrayList<>();
    		for (int i = 5; i > 0; i--) {
    			list.add(i);
    		}
    		List<Integer> list2 = new ArrayList<>();
    		for (int i = 5; i < 10; i++) {
    			list2.add(i);
    		}
    		// 将参数集合中的元素加入到当前list的最后面。(追加)。
    		// list.addAll(list2);
    		// 将参数集合(第2个参数)中的所有元素加入到当前集合
    		// 指定的位置(第1个参数)处。
    		// list.addAll(3, list2);
    		// list.forEach(System.out::println);
    		// 对List中的每一个元素进行替换。
    		// list.replaceAll(t -> t * 2);
    		// 对list元素进行排序。参数为比较器,如果想实现元素
    		// 自然排序,参数传递null值。
    		// list.sort(null);
    		// list.sort((a, b) -> a - b);
    		// 返回指定索引位置的元素。
    		// list.get(0);
    		// 将索引位置的元素(第1个参数)使用第二个参数指定
    		// 的元素进行替换。
    		// list.set(0, 1000);
    		// 在索引位置(第1个参数)插入元素(第二个参数指定)
    		// list.add(0, 1000);
    		// 删除参数指定位置(索引)的元素。
    		// list.remove(0);
    		// 返回参数元素在List中首次出现的位置。
    		// 如果没有出现,返回-1。
    		System.out.println(list.indexOf(12));
    		// 返回参数元素在List中最后一次出现的位置。
    		// 如果没有出现,返回-1。
    		System.out.println(list.lastIndexOf(12));
    		// list.forEach(System.out::println);
    		// 返回List特有的迭代器。指针指向第一个元素之前。
    		ListIterator<Integer> li = list.listIterator();
    		// 返回List特有的迭代器。指针指向参数指定位置的元素之前。
    		// 下次调用next()方法会返回参数指定位置的那个元素。
    		li = list.listIterator(2);
    		// 返回子List,第1个参数指定开始点。第2个参数指定结束点。
    		// 包括起始点,不包括结束点。
    		List<Integer> sub = list.subList(1, 3);
    	}
    
    }
    

      16、

    ArrayList与LinkedList
    List接口有两个常用的实现类:
     ArrayList
     LinkedList
    二者的不同在于: ArrayList底层使用数组来实现的,而
    LinkedList是使用链表(数据域+指针域)的方式实现的。当随
    机访问元素操作多的时候,优先使用ArrayList,当增加与删除
    操作多的时候,优先使用LinkedList。
    

      

    package day14;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.ListIterator;
    
    public class ListIteratorMethod {
    	public static void main(String[] args) {
    		List<Integer> list = new ArrayList<>();
    		list.add(11);
    		list.add(33);
    		ListIterator<Integer> i = list.listIterator(1);
    		// 判断是否存在前一个元素,如果存在,返回true,
    		// 否则返回false。
    		System.out.println(i.hasPrevious());
    		// 返回前一个元素。
    		i.previous();
    		// 返回下一个元素的索引。即下次调用next方法返回元素的索引。
    		i.nextIndex();
    		// 返回前一个元素的索引。即下次调用previous返回元素的索引。
    		i.previousIndex();
    		// 删除最后一次调用next或previous方法返回的元素。
    		i.remove();
    		// 将最后一次调用next或previous方法返回的元素设置(替换)
    		// 成参数指定的元素。
    		i.set(2);
    		// 在当前指针位置之前进行插入。(对下次调用next没有影响)。
    		i.add(100);
    	}
    }
    

      17、set接口

    /*
    * Set接口
    * Set接口中的元素是不允许重复。是否重复
    * 根据equals方法(或compareTo方法)进行判断的。
    * Set接口没有新增的方法(相对Collection接口)。
    */

    18、hashSet实现类

    /*
     * HashSet实现类
     */
    package day14;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class HashSetTest {
    
    	public static void main(String[] args) {
    		Set<Integer> set = new HashSet<>();
    		set.add(100);
    		set.add(-2);
    		set.add(16);
    		set.add(-212);
    		// 没有加入成功,返回false。因为元素重复了。
    		// System.out.println(set.add(-2));
    		// System.out.println(set.size());
    		// HashSet使用元素的哈希码(hashCode)来计算
    		// 元素的存储位置。因此,我们不能保证元素获取的顺序
    		// 与元素加入时的顺序是一致的。
    		set.forEach(System.out::println);
    	}
    
    }
    

      19、LinkedHashSet

    package day14;
    
    import java.util.LinkedHashSet;
    import java.util.Set;
    /*
     * LinkedHashSet
     * LinkedHashSet是HashSet的子类,其底层使用一个
     * 双向链表来维护元素的顺序,因此,获取元素时(遍历元素
     * 时),可以保证获取的顺序与元素加入时的顺序一致。
     */
    
    public class LinkedHashSetTest {
    
    	public static void main(String[] args) {
    		Set<Integer> set = new LinkedHashSet<>();
    		set.add(100);
    		set.add(-2);
    		set.add(16);
    		set.add(-212);
    		set.forEach(System.out::println);
    	}
    
    }
    

      20、SortedSet

    /*
     * SortedSet接口
     * 规范:加入的元素可以自动实现升序排列。
     */
    package day14;
    
    import java.util.SortedSet;
    import java.util.TreeSet;
    
    public class SortedSetTest {
    	public static void main(String[] args) {
    		SortedSet<Integer> set = new TreeSet<>();
    		set.add(100);
    		set.add(20);
    		set.add(50);
    		set.forEach(System.out::println);
    		//TreeSet无参的构造器,使用自然排序。
    		SortedSet<Box> set2 = new TreeSet<>();
    		set2.add(new Box(100));
    		set2.add(new Box(20));
    		set2.add(new Box(50));
    		set2.forEach(System.out::println);
    		// 也可以在创建TreeSet对象时,指定比较器。
    		// 这样就可以指定自己的比较规则。如果我们显式的
    		// 指定了比较器,此时就不会使用自然排序。
    		SortedSet<Box> set3 = new TreeSet<>((a, b) -> b.getValue() - a.getValue());
    		set3.add(new Box(100));
    		set3.add(new Box(20));
    		set3.add(new Box(50));
    		set3.forEach(System.out::println);
    	}
    }
    
    class Box implements Comparable<Box> {
    	private int value;
    
    	public int getValue() {
    		return value;
    	}
    
    	public void setValue(int value) {
    		this.value = value;
    	}
    
    	public Box(int value) {
    		super();
    		this.value = value;
    	}
    
    	@Override
    	public int compareTo(Box o) {
    		return value - o.value;
    	}
    
    	@Override
    	public String toString() {
    		return "Box [value=" + value + "]";
    	}
    }
    

      21、SortedSet接口

    package day14;
    
    import java.util.SortedSet;
    import java.util.TreeSet;
    
    public class SortedSetMethod {
    	public static void main(String[] args) {
    		SortedSet<Integer> set = new TreeSet<>();
    		// SortedSet<Integer> set = new TreeSet<>((a, b) -> b - a);
    		for (int i = 0; i < 10; i++) {
    			set.add(i);
    		}
    		// 返回比较器,如果没有指定比较器,返回null。
    		// System.out.println(set.comparator());
    		// 返回子SortedSet,第1个参数指定起始点,第2个参数指定
    		// 终止点,包括起始点,不包括终止点。
    		SortedSet<Integer> subSet = set.subSet(3, 100);
    		// subSet.forEach(System.out::println);
    		// 返回子SortedSet,从头开始,到参数指定的位置结束。
    		// 不包括参数指定的位置(终止点)。
    		SortedSet<Integer> head = set.headSet(8);
    		// head.forEach(System.out::println);
    		// 返回子SortedSet,从参数指定的位置开始,到Set结束。
    		// 包括参数指定的位置(起始点)。
    		SortedSet<Integer> tail = set.tailSet(3);
    		tail.forEach(System.out::println);
    		// 返回最开始的元素(最小的元素)。
    		System.out.println(set.first());
    		// 返回最末的元素(最大的元素)。
    		System.out.println(set.last());
    
    	}
    
    }
    

      22、 NavigableSet接口  (NavigableSet接口是SortedSet接口的子接口。扩展了一些导航的方法。可以用于更准确的定位)

    package day14;
    
    import java.util.Iterator;
    import java.util.NavigableSet;
    import java.util.TreeSet;
    
    public class NavigableSetMethod {
    	public static void main(String[] args) {
    		NavigableSet<Integer> set = new TreeSet<>();
    		for (int i = 10; i > 0; i--) {
    			set.add(i);
    		}
    		// set.forEach(System.out::println);
    		// 返回小于参数的最大元素。如果不存在,返回null。
    		System.out.println(set.lower(-1));
    		// 返回小于等于参数的最大元素。如果不存在,返回null。
    		System.out.println(set.floor(5));
    		// 返回大于等于参数的最小元素。如果不存在,返回null。
    		System.out.println(set.ceiling(2));
    		// 返回大于参数的最小元素。如果不存在,返回null。
    		System.out.println(set.higher(8));
    		// 删除并返回最开始的元素(最小的元素)。如果没有元素,
    		// 返回null。
    		// System.out.println(set.pollFirst());
    		// 删除并返回最末尾的元素(最大的元素)。如果没有元素,
    		// 返回null。
    		// System.out.println(set.pollLast());
    		// 返回降序排列的NavigableSet
    		NavigableSet<Integer> de = set.descendingSet();
    		// de.forEach(System.out::println);
    		// 返回降序的迭代器
    		Iterator<Integer> iter = set.descendingIterator();
    		iter.forEachRemaining(System.out::println);
    		set.subSet(2, 7);
    		// 第1个参数:起始点,第3个参数:终止点
    		// 第2个参数:是否包含起始点。
    		// 第4个参数:是否包含终止点。
    		set.subSet(2, true, 7, false);
    		set.headSet(8);
    		// 第2个参数指定是否包含终止点。
    		set.headSet(8, false);
    		set.tailSet(3);
    		// 第2个参数指定是否包含起始点。
    		set.tailSet(3, true);
    
    	}
    }
    

      23、NavigableSet接口的实现类
    TreeSetAbstractSet的子类,实现NavigableSet 接口。当
    TreeSet中添加元素时,这些元素会自动进行排序。
    TreeSet默认情况下使用自然排序,但也可自己制定排序方式。
    在创建TreeSet对象时,传递一个实现了Comparator接口的
    类的对象。

  • 相关阅读:
    Core的学习三:容器的使用实例
    Core的学习二:【四步完成】.Net Core中Log4net的使用,配置,【框架.NET5】
    C#7 的一些新语法
    C#6 的一些新语法
    Core的学习一:Core部署在IIS下
    C# 特性【Attribute】【什么是特性?以及特性的一些修饰】
    C#反射
    泛型 -Generic 【why,原理,与普通方法,object的性能对比如何?泛型类、泛型方法、泛型接口、泛型委托,泛型约束,协变 逆变,泛型缓存】
    springboot通过切面编程实现系统请求操作日志记录
    Linux 【安装配置VM虚拟机】
  • 原文地址:https://www.cnblogs.com/liuwei6/p/6574442.html
Copyright © 2011-2022 走看看