Collection 集合 :全部都只能存储应用类型并且是单个存储。
List:有序可重复存储,有序的意思就是存进去什么顺序出来就是取出来就是什么顺序
Set:无序不可重复,无序的意思出进去顺序与取出来的顺序不一定一样。同时保证内部元素唯一性。
SortedSet : 无序不可重复,但是存进去的元素可以进行排序。(可不可以存不同类型的数据,不同类型的数据怎么排序)
ArrayList :采用数组存储数据,所以他的查询效率高增删效率低。(增删需要将很多元素进行位移)
初始化的时候默认大小为10
并且每次扩充的新容量是原来的1.5倍
LinkedList:采用双向链表的存储数据,所有压增删效率高查询效率低(查询需要他去遍历链表)
初始时只有一个head节点 并且data为空。
Vector:底层和ArrayList一样,并且他线程安全,但是它效率低一般不使用这个。
初始化默认大小为10
每次扩充是原来的2倍
Map集合 :全部都是键值对存储。Key是无序不可重复的
HashMap:哈希表/散列表,hashMap中的key相当于set集合
HashTable :线程安全效率低 现在用的很少
SortedMap :key还是按照sortedset一样存储
.....
数据结构
单向链表:
查询:在存储空间上没有规律,所以查询的时候必须从前面第一开始一个一个去找
增删:增加删除的时候只需要将该位置的指针引用改一下就可以。不再指向之前的元素,删除就是跳过要删除的元素指向下一个元素,增加就是指向新的元素,然后新的元素指向下一个元素就可以。
自己写的实现代码 基本思路是这样的
public class Linked {
Eney e;
public Linked() {
// TODO Auto-generated constructor stub
e = new Eney(null, null);
}
//增 不指定位置
public void insert(Object data) {
Eney ele = new Eney(data, null);
Eney head = e;
while(head.next == null) {
head = head.next;
}
head.next = ele;
}
//增 指定位置
public void insert(Object data , int p) {
//先来确定有没有这个元素
Eney head = e;
int i=0;
while(head.next!=null) {
i++;
}
//如果p没有超过元素范围 进行插入
if(p<=i) {
head = e;
i=0;
while(head.next!=null && p!=i) {
head = head.next;
i++;
}
Eney newEney = new Eney(data, null);
newEney.next = head.next;
head.next = newEney;
}
}
//删除
public void delete(int p) {
Eney head = e;
int i=0;
while(head.next!=null) {
i++;
}
if(p<=i) {
//移到要插入的位置上去
i=0;
while(head.next!=null && p!=i) {
head = head.next;
i++;
}
//及时要删除head.next
head.next = head.next.next;
}
}
//查询 //输入位置查询
public Object select (int p) {
Eney head = e;
int i=0;
while(head.next!=null) {
i++;
}
i=0;
if(i>=p) {
while(p!=i) {
i++;
head=head.next;
}
return head.next.data;
}
return null;
}
双向链表:
图我就不画了,大概就是这样的
Public class Linked {
Entry head;
Linked(){
Head.pre = head;
Head.next = head.pre;
Object data = null;
}
//节点
Static class Entry {
Object data;
Entry pre;
Entry next;
}
}
//然后在分别取执行增删改查
小讲一下迭代器,
Collection c =new ArrayList();
Iterator it = c.iterator();
上面这是面向接口编程 其中collection 和 iterator 是接口不是真的实现类
这也体现了多态 父类的接口获取子类对象的实例
其中it是引用,保存了内存地址,指向堆中的迭代器对象,而这个对象的类是实现了Iterator接口的
用迭代器遍历元素
While(it.hasNext()){
Object o = It.next();
Print o
}
小讲一下collection的contains() 集合有没有某个元素?返回boolean
其实最后就是调用的是一个equals() 只要传过来的Object的内容与里面的某个元素一样就会返回一个true。就是看你内容是不是一样。
注意****如果是存入的参数是一个我们写的实体类比如
Class User{
String name ;
Int age;
}
- add(“a”,12);
User user = User(“a”,12);
Contains(user); //这里返回的是false 因为这个类比较的是引用
/**但是这不符合实际的业务需求 因为实际的业务中我们就是认为他们是相等的 因此我们应该重写这个equals()方法 */
因为在调用这个equals()方法的时候使用 user.equals() 这个方法 所以我们将equals()写在User里面
代码如下: 自己写的代码已经测试过没有错误。
package connection;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionEqual {
public static void main(String[] args) {
User user1 = new User("jzwen",12);
Collection<User> c = new ArrayList<User>();
c.add(user1);
User user2 = new User("jzwen", 12);
System.out.println(c.contains(user2));
}
}
class User{
String name ;
int age ;
public User(String name,int age) {
this.age = age;
this.name = name;
}
public boolean equals(Object o) {
//引用是一样的
if(this==o) {
return true;
}
//首先他需要属于这个类
if(o instanceof User) {
//将Object转换成User对象
User user = (User)o;
if(this.name == user.name && this.age == user.age) {
return true;
}
}
return false;
}
}
//特别记住这是很重要的,在开发中挺实用的。记得要去重写这个equals方法,要不然你都不知道怎么错的。然后我这里只写了contains这个方法作为例子,还有remove方法等其他方法都是要这个equals
因为Object的equals方法比较的是引用,而我们的现实中就是想去比较内容。所以千万在存储元素类中重写equals方法
使用迭代器删除元素
这里会出现问题就是如果是使用迭代器自身的it.remove() 没有问题
但是如果我们使用c.remove(element) c导致c中的元素发生改变,需要生成一个新的迭代器重新去操作这个集合,如果还用原来那个迭代器的话会发生错误。
Hash表:
底层其实是一个数组,数组里面存了一个链表,也就是存了一个头结点。
Final int hash 这是一个hsah值 是key调用hashcode()得到的值再通过hash算法得到的。
头结点里面存的是
简述一下过程,hashMap的Object get(Object key) void put(Object key , Object value)
Get : key通过hashCode()再通过哈希算法得到hash值,然后去看数组中找到这个hash值,然后对应的返回value (应该是返回那个链表)
Put : key-------得到hash值,去看他是不是存在,不存在的话就在对应链表里面插入值,如果存在的话就去找有那个链表上有没有和key一样的值,调用key.equals()进行比较。
另外hashset和hashMap的初始大小都是16,加载因子是0.75,也就是说当前容量到了12就进行扩量。
sortedSet接口 实现类treeSet类 里面采用二叉树存储数据
他会排序的主要原因是他要实现一个compareTo()方法
要是我们自己写了一个实体类的话 我们要自己去实现这个接口,并写这个方法,如上我们比较的是age。
另一种方式
SortedSet s = new treeSet(里面要传一个比较器); 不传的话就使用默认
New UserCompared()
Class User{
Int age;
String name;
}
自己写一个比较器 差不多伪代码
Class UserCompared implements Comparator
{
//实现compare方法
Public int compare(Object o1 , Object o2){
If(o1 instanceof User && o2 instanceof User){
User user1 = (User)o1;
User user2 = (User)o2;
Return user1.age-user2.age;
}
}
}
hashMap默认初始化是16 默认加载因子0.75
hashTable默认初始化11 默认加载因子0.75
Map中的也需要需要重写equals()和hashCode()
注意 添加的元素是 当key相同的时候后面那个value会将前面的value覆盖。
Collections 工具类可以对List集合排序,但是集合中的元素必须是可比较的,
Set s = new HashSet();
List l = new ArrayList(s); //将set集合转换为List集合
Collections.sort(l); //只可以对set集合进行排序,
当List集合中的元素是这样的对象
Class User{
Int age ;
String name;
}
我们就要重写Compare()
Public int Compare(Object o1 , Object o2){
}
或者实现Comparable接口
将ArrayList转换为线程安全的 使用Collections