java数据结构篇(一)

一、数据结构
数据结构主要包括三个方法的问题,第一能够被计算机所处理的数据特别是一些复杂数据,它们应该如果组织在一起成为一个整体以方便进行管理,存储,处理。第二对于这些复杂数据进行管理、存储和处理时应该采用什么样的标准算法才能够正确地完成以上的任务。第三对特定结构的数据采用的算法可以有多种,不同的算法谁好谁坏需要作出判断与选择。

二、java中的数据结构
通过对集合框架整体架构的认识,jdk提供了很多的集合接口及类型(抽象类及实现类),因此集合框架就是一堆复杂的数据,不同的集合它内部数据的组织形式是不一样的,所提供对集合的操作算法的实现原理和方式差异很大,不同集合在实现元素的存储和管理过程中具有不同的特性,这些特性决定了在应用中应该适用的场合。
Java中的数据结构主要针对于数组和集合类型中的实现原理及具体应用。

三、java中常见的数据结构
1、堆栈
堆栈是建立在线性表(一组数据,有一个头元素,也有一个尾元素,所有的元素按照特定的顺序进行排列,典型的实现是数组)的基础上的一种数据结构,也是线性表的一种具体实现方式。它的主要特征是先进后出,后进先出,主要操作就是压栈和出栈。
Java中实现堆栈的api,典型有两种,一个是Stack集合,另一个是LinkedList集合。

  Stack<String> stack = new Stack();
//进栈,元素增多
stack.push("1111");
stack.push("2222");
stack.push("3333");
//出栈,栈中的元素会减少直到为空
String e1 = stack.pop();
String e2 = stack.pop();
//String e3 = stack.pop();
System.out.println(e1+" "+e2);
String peek = stack.peek();
System.out.println(peek);

堆栈的实际运用,最基础的应用在jvm中
在这里插入图片描述

2、队列
也是基于线性表的一种比较特殊的数据,它的特点就是先进先出,后进后出。
Java中提供比较的队列类型,一般队列都实现了Deque或Queue这两个接口。
Deque,实现该接口的队列属于双端队列”,两头都可以插入和删除元素。
Queue:提供先进先出,后进后出的队列。
Java中的主要队列都同时实现了以上两个接口。
在实际的设计过程中,如果要使用队列基本上要遵循队列的使用规律。
一个java基于数组存储元素的阻塞队列的例子

   //创建队列对象,该队列是有界的,以下队列最多存放5个元素,此队列严格遵循先进先出,后进后出
ArrayBlockingQueue<String> abq = new ArrayBlockingQueue<String>(5);
//创建一个线程,该负责向队列的尾部插入元素
new Thread(){
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);//当前线程休眠一秒
                int r = new Random().nextInt(1000);
                abq.put(r+"");//向队列添加元素,如果队列满了会阻塞直到队列有空的位置再放入
                System.out.println("放入的元素是:"+r);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}.start();
//创建一个线程,负责从队列的头部取出元素
new Thread(){
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(2000);
                String e = abq.take();//如果队列是空的也会阻塞直到有元素进来
                System.out.println("取出的元素是:"+e);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}.start();

在java应用程序内部,队列的作用主要是有不同的线程之间实现数据的通讯。
现在很多大型的应用程序都使用到了队列,这些队列是一些公司设计出来的软件产品。很多应用在运行时都需要与其它的应用进行数据传递,比如淘宝购物,下单由淘宝的系统完成,收款由支付宝或微信完成,此种就利用了消息来传递订单和用户的信息及商家的信息。
3、链表
也是一种线性表,表中的元素具有连接关系,所所谓的连接就是在元素的内部保存了一份它前面或后面元素的地址。
单向链表:
在这里插入图片描述

寻找元素从一端开始,元素占用空间少,查找元素的效率低
双向链表:
在这里插入图片描述

寻找元素可以从任一端开始,元素占用空间大,查找元素的效率较单向要高一些

链表的特点:有序的,查找慢,增删快。与数组的特点相反。

Java 提供多个基于链表这种结构的api,它们都属于集合框架中的实现类型。LinkedLst.

4、红黑树
树在数据结构中的定义,有一个根点,每个节点可以有多个子结点,如果结点没有子结点,这种结点就是叶子结点。
在这里插入图片描述

二叉树,一个节点最多有两个子结点。

在这里插入图片描述

红黑树本身就是二叉树,只不过不同类型的节点为标记为黑色或红色。
特征:它是有序的,先上后下,先左后右。
Java中提供了以tree作为元素组织的形式的集合类型,比如TreeSet,TreeMap。
树形集合的最大特征就是有序性,另外就是查找元素速度快,元素越多,速度快的特征越明显。
在数据库的表中,可以创建索引,索引就象书的目录,在表中可以通过索引来快速查询数据记录。主流数据库中表索引的结构都是二叉树,它们查找记录的速度最快,记录越多速度更快,速度的提升与元素的个数呈对数级。

四、LIst接口
实现了List接口的集合类型统称为List集合。它继承自Collection接口,它拥有Collection接口的所有方法,作为子接口也应该有自已的方法,这些方法都与索引有关系。
实现List接口的集合都具有以下共同特点:
1、元素是有序的。
2、可以通过元素索引来使用元素。
3、集合中的元素可以重复(相同的对象可以在集合中有多份)
4、在这里插入图片描述

5、List的实现类主要有两个,一个ArrayList,一个是LinkedList。

五、LinkedList 集合
该集合实现了List接口,因此它就具有利用索引来使用元素的方法,也符合List的基本特征,有序的。
内部元素的存储是采用链表的形式,而且是双向链接。因此,这种集合不适合于大量查询的场合,适合于大量增加和删除的操作。
实现了队列相关的接口,所以它拥有一些针对头尾操作元素的方法,所以在某些场合可以当作队列使用。
它有push和poll方法,也可以作为堆栈使用。

LinkedList<String> ll = new LinkedList<>();        
//如果就当作有序的集合使用,使用的主要方法如下:
ll.add("aaa");
ll.remove(0);
//如果当队列使用
ll.addFirst("");
ll.addLast("");
//当堆栈使用
ll.push("");
String pop = ll.pop();
//使用该集合要体现在增删操作比较多的情况
ll.add(2,"");

六、Set接口
继承自Collection接口,实现该接口的集合类型主要有两个,一个是HashSet,一个是TreeSet;实现Set接口的集合元素不能重复;另一个就是无序。因此,Set接口中并没有象List接口中的依据索引来操作元素的方法。

七、HashSet集合
该集合符合Set接口的规定,元素不能重复,元素无序。其内部的存储方式比较复杂,它存储元素采用的是称为”桶”的容器,桶是内存中的一块区域,集合中的元素依据它的哈希码来决定该元素应该放在哪个桶中,因此元素的哈希决定了元素在集合中的位置,因此元素的位置具有不确定性。
集合中的元素不能重复,它的判断依据就是两个对象之间的比较方法(equals方法),如果元素未重写equals方法,就会判断两个元素的地址是否一致,如果一致它们就是重复的元素。另外,放入集合中的元素有可能会重写hashCode()和equals()方法,此时判断重复元素的标准就会发生变化,这就可能造成两个对象的所有属性值是相同的情况下,它们不能存在于同一集合中。
如果两个元素的哈希玛相同,这两个元素就要放在同一桶中,就会存在一种情况,一个桶中有多个元素,同一个桶中的多个元素要有一个合理的组织方式,不同版本jdk的组织方式不一样,1.8中的组织方式就是采用链表的方式来组织同一桶中元素,如果链表中的元素个数超过了8个(查询效率就会低),又会采用红黑树的方式来组织(有序,二分查找法,速度快)。

八、可变参数
就是在方法的参数列表中,参数可以定义为传入多个数据的参数。
Void method(数据类型… 参数名)
可变参数其实就是一个数组,在方法内部可以把该参数当作数组使用。
如果参数列表中有多种类型的参数,可变参数只能出现在最后.

String[] strs = {"a1","a2","a3"};
   // test("","a1","a2","a3");
    test("",strs);
}
static void test(String str,String...changedParam){
    System.out.println(changedParam.length);
}

九、Collections 集合工具类,在util包中
提供了大量针对集合操作的方法,这些方法都是静态的。
1、public static <T extends Comparable<? super T>> void sort(List list)
用来排序List集合。
2、List集合中的元素要实现Comparable接口
Comparable 接口:可比较接口,如果对象实现了该接口,那么对象之间就可以进行大小比较。String 实现了它,因此字符串具有大小之分。
在compareTo方法中,必须返回大于0 ,小于0或者等于0的结果(一定要遵守),告诉Collections类比较的结果。另外,参与比较的对象属性如果是基本类型绝没有问题它们可以的直接比较大小(> < == ),如果是引用类型该类型也必须要实现Compareble接口,否则无法比较大小。

2、public static void sort(List list, Comparator<? super T> c)
与上面的方法具有重载关系,但是本方法,多了一个参数,Comparator类型的参数;另外,本方法的泛型声明没有要求参与比较的对象是 Comparable的子类。如果调用这个方法来完成排序,被比较的元素对象不需要实现Comparable,大小关系通过Comparator的实现类来完成。
3、两种方法的区别
如果某个类的对象必须要能够区分出大小,该类就应该实现Comparable接口,所以该接口在lang包中,具有基础性的地位。
如果要调用Collections.sort(二个参数)的方法来排序,则使用Comparator接口,所以该接口在util包中,具有工具性的地位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值