剩余任务:1,常见的集合类总结,底层原理和常见的API ;2,自定义一个正则表达式,从指定字符串中查找满足条件的内容并输出;3,比较String,StringBuffer,StringBuild的区别,有哪些常见的操作API;4,JDBC程序

1,List,Set都是继承Collection接口,都是用来存储一组相同类型的元素;

  特点:List:元素有序放入顺序,元素可重复

     Set:元素无放入顺序,元素不可重复,所以有时候可以使用Set来去重,在插入的时候,set在元素插入时是要有一定的方法来判断是否重复

  List主要有ArrayList,LinkList,Vector这些实现

    ArrayList本质就是数组,使用set和get方法来进行访问的,由于是数组的数据结构,所以在数据中部新增数据或者删除数据的话,底层就会复制原来的数据到新开辟的内存中,再将原来的数据删除,这就影响到性能,

        但是查询数据会很快;

    而LinkList是一个双链表,在添加和删除数据方面是优于ArrayList的,但是由于是链表结构,在查询上,每次都需要从头结点开始,从而影响查询的速度

   但是,ArrayList在设计好数组的大小,并采用尾插法的话,性能是很有可能优于LinkList;

  Vector和ArrayList类似,但属于强同步类。如果线程本身就是线程安全的话,那么使用ArrayLIst是更好的选择;两者在更多元素添加进来会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%;

  LiskList还实现了Queue接口,该接口比List提供了更多的方法,包括offer(),peek(),poll()等;

    还有一点,Vector是多线程环境下更为可靠的数据结构,所有方法都实现同步;

开发二组,剩余第二周作业总结_数据

 

List可添加null;

开发二组,剩余第二周作业总结_数据库_02

 

 

 使用List来实现存在效率非常低的问题,而Map这种键值(key-value)映射表的数据结构,作用就是能高效通过key快速查找value(元素)!

Set是如何保证元素的不重复?

  Set实现方式分为HashSet和TreeSet,而HashSet底层是HashMap实现的,HashMap在添加值的时候,会计算其HashCode值,从而找到对的位置;

                    TreeSet底层是TreeMap的keySet(),而TreeMap是基于红黑树实现的,红黑树是一种平衡二叉树查找数,是按key排序的,所有元素在插入时,TreeSet会用compareTo()判断重复元素的

Properties:

在编写应用程序的时候,经常需要读写配置文件。例如,用户的设置:

# 上次最后打开的文件:
last_open_file=/data/hello.txt
# 自动保存文件的时间间隔:
auto_save_interval=60

配置文件的特点是,它的Key-Value一般都是String-String类型的,因此我们完全可以用Map<String, String>来表示它。

因为配置文件非常常用,所以Java集合库提供了一个Properties来表示一组“配置”。由于历史遗留原因,Properties内部本质上是一个Hashtable,但我们只需要用到Properties自身关于读写配置的接口。

Queue:

队列(Queue)是一种经常使用的集合。Queue实际上是实现了一个先进先出(FIFO:First In First Out)的有序表。它和List的区别在于,List可以在任意位置添加和删除元素,而Queue只有两个操作:

  • 把元素添加到队列末尾;
  • 从队列头部取出元素。

  在Java的标准库中,队列接口Queue定义了以下几个方法:

    •   int size():获取队列长度;
    •   boolean add(E)/boolean offer(E):添加元素到队尾;
    •   E remove()/E poll():获取队首元素并从队列中删除;
    •   E element()/E peek():获取队首元素但并不从队列中删除;   
    • 对于具体的实现类,有的Queue有最大队列长度限制,有的Queue没有。注意到添加、删除和获取队列元素总是有两个方法,这是因为在添加或获取元素失败时,这两个方法的行为是不同的。我们用一个表格总结如下:                                                                           
throw Exception 返回false或null
添加元素到队尾 add(E e) boolean offer(E e)
取队首元素并删除 E remove() E poll()
取队首元素但不删除 E element() E peek()

使用Stack   

 

栈(Stack)是一种后进先出(LIFO:Last In First Out)的数据结构。所谓FIFO,是最先进队列的元素一定最早出队列,而LIFO是最后进Stack的元素一定最早出Stack。如何做到这一点呢?只需要把队列的一端封死:

因此,Stack是这样一种数据结构:只能不断地往Stack中压入(push)元素,最后进去的必须最早弹出(pop)来

Stack只有入栈和出栈的操作:

  • 把元素压栈:push(E)
  • 把栈顶的元素“弹出”:pop()
  • 取栈顶元素但不弹出:peek()

在Java中,我们用Deque可以实现Stack的功能:

  • 把元素压栈:push(E)/addFirst(E)
  • 把栈顶的元素“弹出”:pop()/removeFirst()
  • 取栈顶元素但不弹出:peek()/peekFirst()

为什么Java的集合类没有单独的Stack接口呢?因为有个遗留类名字就叫Stack,出于兼容性考虑,所以没办法创建Stack接口,只能用Deque接口来“模拟”一个Stack了。

当我们把Deque作为Stack使用时,注意只调用push()/pop()/peek()方法,不要调用addFirst()/removeFirst()/peekFirst()方法,这样代码更加清晰。

Iterator:

Java的集合类都可以使用for each循环,ListSetQueue会迭代每个元素,Map会迭代每个key。

2,自定义一个正则表达式,从指定字符串中查找满足条件的内容并输出

在软件开发中,正则表达式是个很有用的功能,使用正则表达式可以简化代码,省去不少时间。
下面记录一个正则表达式的用法,就是找出一堆乱码中,找出以1开头的电话号码,并写入一个文件中

废话不多说,直接上代码:

开发二组,剩余第二周作业总结_数据库_03

 

 

 12.txt里面是一堆乱码,其中也含有一堆数字,就可能有电话号码。在网络数据爬取的时候,就需要正则表达式来提取有用的信息,就比如特定格式的电话号码。

Parrern对象获取规则,用Matcher对象里的方法find()去查找可能的值,被存储到Mather里的group()方法中。

3,比较String,StringBuffer,StringBuild的区别

  String是final修饰的,是不可变的,每次操作都会产生新对象,而StringBuffer、StringBuilder都是在原对象上操作

  StringBuffer是线程安全的,StringBuilder是线程不安全的,因为StringBuffer都是synchronized修饰的

  性能:StringBuilder > StringBuffer > String

开发二组,剩余第二周作业总结_正则表达式_04

 

 

 参考博客:https://blog.csdn.net/itchuxuezhe_yang/article/details/89966303

开发二组,剩余第二周作业总结_数据库_05

 

 

 String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

这里使用10000次对String、StringBuilder和StringBuffer对象进行修改操作,计算完成时间并打出来,结果可以看出,Sring的完成时间最长,StringBuilder和StringBuffer的执行时间差不多。

4,JDBC程序

JDBC是Java DataBase Connectivity的缩写,它是Java程序访问数据库的标准接口。

使用Java程序访问数据库时,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而JDBC接口则通过JDBC驱动来实现真正对数据库的访问。

例如,我们在Java代码中如果要访问MySQL,那么必须编写代码操作JDBC接口。注意到JDBC接口是Java标准库自带的,所以可以直接编译。而具体的JDBC驱动是由数据库厂商提供的,例如,MySQL的JDBC驱动由Oracle提供。因此,访问某个具体的数据库,我们只需要引入该厂商提供的JDBC驱动,就可以通过JDBC接口来访问,这样保证了Java程序编写的是一套数据库访问代码,却可以访问各种不同的数据库,因为他们都提供了标准的JDBC驱动:

Java App ————>JDBC Interface(JDK)————>JDBC Driver(Vendor)————>Database

JDBC接口的Connection代表一个JDBC连接;

使用JDBC查询时,总是使用PreparedStatement进行查询而不是Statement

查询结果总是ResultSet,即使使用聚合查询也不例外。

连接数据库几个参数值得注意,其他的没啥了

开发二组,剩余第二周作业总结_数据结构_06

 

 用最新的驱动(Driver),以及getConnection中url地址一定得填对,后面就是账号密码

获取连接后,我们就可以写sql语句来操作数据库了

开发二组,剩余第二周作业总结_数据结构_07

 

 这个用增加和修改的例子来演示

我们在讲多线程的时候说过,创建线程是一个昂贵的操作,如果有大量的小任务需要执行,并且频繁地创建和销毁线程,实际上会消耗大量的系统资源,往往创建和消耗线程所耗费的时间比执行任务的时间还长,所以,为了提高效率,可以用线程池。

类似的,在执行JDBC的增删改查的操作时,如果每一次操作都来一次打开连接,操作,关闭连接,那么创建和销毁JDBC连接的开销就太大了。为了避免频繁地创建和销毁JDBC连接,我们可以通过连接池(Connection Pool)复用已经创建好的连接。

这里就不演示了。