容器也是一个集合
存储多个数据长度可以随着内容的多少进行改变可以存储任意类型的数据数组:
长度一旦确定不可改变存储相同类型的数据有序(索引)、存储多个数据collection 存储字符串类型的数据
Map键值对形式数据的 容器体系
只存储字符串类型的数据
添加功能:这里添加数据相当于把数组重新拷贝一份,新加的数据在新数组的后面删除功能:相当于新拷贝一份数组,删除的在新数组中不拷贝修改功能:查询功能容器体系的上层接口,是集中,收集的意思表示一组对象,这些对象也称为collection的元素,一些collection允许有重复的元素,另一些则不允许,一些collection是有序的,而另一些则是无序的。
collection有两个子接口:
Set中的数据没有顺序,不可重复 List中的数据有顺序,可重复容器类中可存放不同的类型的数据,但是必须都为引用数据类型的数据,基本数据类型会自动装箱
方法返回值作用CRUDadd(E e)boolean添加元素Csize()int返回容器大小Rcontain(Object o)boolean包含(引用类型重写equals)RisEmpty()boolean容器是否为空Requals(Object o)boolean比较两个容器内容是否相同Rremove(Object o)boolean删除元素Dclear()void清空容器DtoArray()Object[]所有元素存放在数组中toArray(T[] a) T[]retainAll(Collection<?> c)boolean求交集intertorIterator遍历遍历使用原因:JDK1.4以前的类型不明确,装入集合的类型都被当做Object对待,从而失去自己的实际类型,从集合去除时往往需要转型,效率低,容易产生错误
优点:增强程序的可读性和稳定性
使用泛型,保留了容器中元素的类型,安全省心的使用容器。
Iterator对象称作迭代器,Iterator方法用以返回一个实现了Iterator接口的对象,方便的实现对容器内元素的遍历操作。
Iterator接口定义了如下方法:
boolean hasNext();判断是否有元素没有被遍历Object next();返回游标当前位置的元素并将游标移动到下一个位置void remove();删除游标前面的元素迭代器的三步骤:
获取对象判断是否存在下一个获取元素位置允许有元素重复,新增了一些根据索引操作的方法
方法返回值作用CRUDadd( index,E element)void指定位置添加元素C增get(int index)E获取指定位置元素(for遍历)R查indexOf(Object o)int元素第一次出现的 索引(重写equals)RlastIndexOf(Object o)int元素最后一次出现的索引Rset(int ,E)E覆盖元素,返回覆盖前的元素U改remove(int,int )E删除指定索引的元素,返回该元素获取子集合D删subList(int,int)List获取子集合其他listIterator()ListIterator可以反向输出遍历ArrayList 是 List 的子类,允许存放重复元素,因此有序。集合中元素被访问的顺序取决于集合的类型。如果对 ArrayList 进行访问,迭代器将从索引 0 开始, 每迭代一次,索引值加 1。然而,如果访问 HashSet 中的元素,每个元素将会按照某种随机的次序出现。虽然可以确定在迭代过程中能够遍历到集合中的所有元素,但却无法预知元素被访问的次序。
底层实现:由可变数组实现,通过数组拷贝实现容器可以根据内容进行动态扩容
优点:遍历和获取的时候效率高,因为数据根据索引操作效率高
缺点:增删效率低,大量涉及到数组拷贝问题
扩容:使用Arrays和copyOf方法进行扩容,每次扩容原容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity没有新增方法,可以多态
应用场景:单线程环境下,在大量做查询的业务下,适合使用ArrayList容器
**removeFirst**() 移除并返回此列表的第一个元素。
**removeLast**() 移除并返回此列表的最后一个元素。
package test14; //单链表 public class LinkedList { public static void main(String[] args) { MyLinkedList my=new MyLinkedList(); my.add("莫问"); my.add("相知"); my.add("花间"); System.out.println(my.size()); System.out.println(my.get(0)); System.out.println(my.get(1)); System.out.println(my.get(2)); } } //定义容器类 class MyLinkedList{ //记录链表头节点 private Node head; //记录容器中数据的个数 private int size; public MyLinkedList() { } //添加数据的方法 public void add(String value){ Node node=new Node(value,null); //第一次添加,当前节点作为链表头存在 if(head==null){ head=node; size++; return; } //每次加节点都在链表的尾部添加,当前添加节点赋值给原链表的最后一个节点的nextNode属性 Node temp=head; //temp指向最后一个节点 while(true){ //temp作为最后一个节点出现,最后一个节点记录下一个节点的地址为null if(temp.getNextNode()==null){ temp.setNextNode(node); break; } temp=temp.getNextNode(); } size++; } public int size(){ return this.size; } //根据索引获取的方法 public String get(int index){ //判断索引 if(index<0||index>size){ return "索引越界"; } Node temp=head; for(int i=0;i<index;i++){ //temp指向下一个节点 temp=temp.getNextNode(); } return temp.getData(); } } //节点 class Node{ //存储的数据 private String data; //下一个节点的地址 private Node nextNode; public String getData() { return data; } public void setData(String data) { this.data = data; } public Node getNextNode() { return nextNode; } public void setNextNode(Node nextNode) { this.nextNode = nextNode; } public Node(String data, Node nextNode) { super(); this.data = data; this.nextNode = nextNode; } @Override public String toString() { return "Node [data=" + data + ", nextNode=" + nextNode + "]"; } }LinkedList:底层用双向链表实现的 List。特点:查询效率低,增删效率高,线程不安全。
ArrayList:底层用数组实现的 List。特点:查询效率高,增删效率低,线程不安全。
Vector:底层用数组实现的 List,特点:线程安全,效率较低。
线程安全用Vector,线程不安全,查找较多用ArrayList,增删元素较多用LinkedList.
内部比较器(自然排序):实现Comparable接口,重写comparaTo方法,在方法中自定义比较规则,默认类型的比较规则,默认升序
p1.compareTo(p2) ,返回值<0 p1<p2 返回值=0 相等 返回值>0 p1>p2外部比较器(自定义比较器):实现接口java.util.Comparator的接口,重写compare()方法,方法中自定义比较规则
//static void sort(T[] a, Comparator<? super T> c) 第二个参数中定义当前排序的比较规则int compare(T o1, T o2) 比较用来排序的两个参数。
public class Compare { public static void main(String[] args) { Person p1 = new Person("王大", 30); Person p2 = new Person("王二", 20); Person p3 = new Person("王三", 28); Person p4 = new Person("王四", 40); Person p5 = new Person("王五", 20); Person[] p = { p1, p2, p3, p4, p5 }; System.out.println(Arrays.toString(p)); Arrays.sort(p); System.out.println(p1.compareTo(p2));//没法比较,默认是Object类型的比较,类型不同 //外部比较器 //static <T> void sort(T[] a, Comparator<? super T> c) 第二个参数中定义当前排序的比较规则 Arrays.sort(p, new Comparator() { @Override public int compare(Object o1, Object o2) { return ((Person) o2).getAge() - ((Person) o1).getAge(); } });//匿名内部类中重写比较方法 System.out.println(Arrays.toString(p)); } } class Person implements Comparable<Person> { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } // 自定义比较,默认试试升序 @Override public int compareTo(Person o) { // TODO Auto-generated method stub return 0; } // 内部比较器 /* * @Override public int compareTo(Person o) { 根据年龄升序排序 return (int) * (this.getAge() -o.getAge()); //根据年龄降序排序 //return (int) (o.getAge() * -this.getAge()); } */ }无序,不含重复元素,
add(E e) 如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。addAll(Collection<? extends E> c) 如果 set 中没有指定 collection 中的所有元素,则将其添加到此 set 中(可选操作)。clear() 移除此 set 中的所有元素(可选操作)。equals(Object o) 比较指定对象与此 set 的相等性。contains(Object o) 如果 set 包含指定的元素,则返回 true。hashCode() 返回 set 的哈希码值。remove(Object o) 如果 set 中存在指定的元素,则将其移除(可选操作)。size() 返回 set 中的元素数(其容量)。 Set<String> set=new HashSet(); set.add("四海王气闲"); set.add("地方"); set.add("个人股"); set.add("过他"); set.add("过他"); //数据存放顺序和添加的不一定一致,但是一旦确定不会改变 System.out.println(set);//[地方, 四海王气闲, 个人股, 过他]去重且无序 System.out.println(set);//[地方, 四海王气闲, 个人股, 过他]一旦确定不会改变 set.remove("个人股"); //移除 System.out.println(set); } }**HashSet:**底层是由Hashmap维护
底层:哈希表(hashtable)
特点:查询,增删效率高,但是无序,不可重
如果两个对象Hashcode()值相同,不一定是一个对象,需要进一步比较equals()
如果两个对象的hashscode()值不相同,肯定不是一个对象
自定义引用数据类型去重问题:重写hashcode()和equals()方法,计算桶的位置时根据对象的内容计算而非地址
构造方法:
HashSet() 构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75HashSet(Collection<? extends E> c) 构造一个包含指定 collection 中的元素的新 setHashSet(int initialCapacity) 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。HashSet(int initialCapacity, float loadFactor) 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。 public static void main(String[] args) { //定义一个HashSet容器,存放Person类型的对象,达到去重的效果,认为:对象的所有成员属性值都相同,就是相同的对象 HashSet<Person> set=new HashSet(); set.add(new Person("王大", 20)); set.add(new Person("王二", 40)); set.add(new Person("王三", 26)); set.add(new Person("王二", 40)); System.out.println(set);//没有去重 } //Person类中 //重写equals并没有去重 public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } 重写hashcode和equals去重 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; }TreeSet:
底层:是TreeMap,红黑树,平衡二叉树的一种
优点:默认升序排序
使用元素的自然排序对元素进行排序,或者根据创建set时提供的conparator进行排序
使用场景:去重,对多个数据存在自定义排序的,没有索引,
不想要自定义排序,可用hashset想有索引 ArraysList线程安全 vector增删比较多还有索引,LinkedList public static void main(String[] args) { // TreeSet(Comparator<? super E> comparator) TreeSet<Person> tree = new TreeSet<Person>(new Comparator<Person>() { @Override // 去重+排序的原则 public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } }); tree.add(new Person("王大", 18)); tree.add(new Person("王二", 17)); tree.add(new Person("王三", 20)); System.out.println(tree); System.out.println(tree.last()); System.out.println(tree.first()); } }基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,
适用于按自然顺序或自定义顺序遍历键(key)。
去重和排序都按照比较规则进行操作 内部和外部比较器
