3.Collection接口和Conllections工具类的区别
集合转换为数组:
数组转换为集合:(asList())
ArrayList集合特有的方法
ArrayList集合和数组的区别
Vector集合特有的方法
LinkedList集合中的特有方法
poll方法与pop方法有什么区别?
自然排序
比较器排序
Collection集合体系中的集合皆为单列集合.Map集合才是双列集合(后面会详细介绍的!).
Colletion是集合的根接口,其子接口List和Set分别继承根接口.而ArrayList集合,LinkedList集合以及Vector集合是List集合的实现类.HashSet集合,LinkedHashSet集合以及TreeSet集合是Set集合的实现类.Collection,List,Set接口中的方法,其相对应的实现类也就可以直接使用,因为继承下来了.每个实现类不仅继承了其父接口中的方法,还都有自己独特的方法.
除此之外单列表集合还有一个针对集合操作的工具类Collections类,里面有很多常用的静态方法.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test1 {
public static void main(String[] args) {
//Collections工具类中给方法
ArrayList list = new ArrayList<>();
list.add(20);
list.add(24);
list.add(25);
list.add(22);
list.add(20);
list.add(26);
//list.sort();
Collections.sort(list, new Comparator() {
@Override
public int compare(Integer a, Integer b) {
return a - b;
}
});
System.out.println(list); //[20, 20, 22, 24, 25, 26]
//二分查找,元素必须有序
int index = Collections.binarySearch(list, 24);
System.out.println(index); //3
//获取最大最小值
Integer max = Collections.max(list);
Integer min = Collections.min(list);
System.out.println(max); //26
System.out.println(min); //20
//反转
Collections.reverse(list);
System.out.println(list); //[26, 25, 24, 22, 20, 20]
//随机置换
Collections.shuffle(list);
System.out.println(list); //[25, 20, 20, 22, 26, 24]
}
}
Collection接口是集合中的根接口,里面有很多方法,会被子接口以及实现类所继承和使用.
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
//Collection
Collection c1 = new ArrayList(); //多态,ArrayList是实现类
//往集合中添加元素
c1.add("aaa");
c1.add("bbb");
c1.add("ccc");
c1.add("ddd");
c1.add("eee");
Collection c2 = new ArrayList();
c2.add("aaa");
c2.add("bbb");
c2.add("ccc");
//集合只能存储引用数据类型的元素。
int num = 100;
c1.add(num); //Integer 自动装箱
c1.add(3.25);//Double
System.out.println(c1); //[aaa, bbb, ccc, ddd, eee, 100, 3.25]
boolean b = c1.addAll(c2);
System.out.println(b); //true
//删除集合中的某个元素
boolean b2 = c1.remove("aaa");
if (b2) {
System.out.println(c1); //[bbb, ccc, ddd, eee, 100, 3.25, aaa, bbb, ccc]
}
//c1 会删除掉两个集合的交集元素,c2的元素不影响。
boolean b3 = c1.removeAll(c2); //如果有交集元素被删除,返回true,没有交集元素被删除返回false
System.out.println(b3); //true
System.out.println(c1); //[ddd, eee, 100, 3.25]
System.out.println(c2); //[aaa, bbb, ccc]
//a集合.containsAll(b集合); 看a集合是否包含了所有b集合的元素,如果包含了返回true ,如果有一个没有包含就会false
boolean b4 = c1.containsAll(c2);
System.out.println(b4); //false
//获取长度的方法
int size = c1.size();
System.out.println(size); //4
//清空集合
System.out.println(c2); //[aaa, bbb, ccc]
c2.clear();
System.out.println(c2); //[]
}
}
package com.xingyun.test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
//遍历集合
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 24);
Student s3 = new Student("王五", 25);
Collection list = new ArrayList();
list.add(s1);
list.add(s2);
list.add(s3);
//获取迭代器,来遍历集合中的元素
//接口 Iterator 对 collection 进行迭代的迭代器。
//boolean hasNext()
// 如果仍有元素可以迭代,则返回 true。
// E next()
// 返回迭代的下一个元素。
Iterator iterator1 = list.iterator();
while (iterator1.hasNext()) {
Student stu = (Student) iterator1.next();
System.out.println(stu.getName() + "====" + stu.getAge());
}
//结果:
/*
张三====23
李四====24
王五====25
*/
}
}
import java.util.*;
public class Test {
public static void main(String[] args) {
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 24);
Student s3 = new Student("王五", 25);
Collection list = new ArrayList();
list.add(s1);
list.add(s2);
list.add(s3);
//集合转换为数组
//遍历放入到数组中
Student[] arr = new Student[list.size()];
Iterator iterator2 = list.iterator();
int index = 0;
while (iterator2.hasNext()) {
Student stu = (Student) iterator2.next();
arr[index++] = stu;
}
System.out.println(Arrays.toString(arr));
//[Student{name='张三', age=23}, Student{name='李四', age=24}, Student{name='王五', age=25}]
System.out.println("====================================");
//toArray()
Object[] objects = list.toArray();
System.out.println(Arrays.toString(objects));
//[Student{name='张三', age=23}, Student{name='李四', age=24}, Student{name='王五', age=25}]
//数组转换为集合
//面对一个数组时,是把数组中的的元素取出来放到集合中
Integer[] arr1 = {20, 30, 40};
List integers = Arrays.asList(arr1);
System.out.println(integers);
//传入的是两个以上的数组,是把数组放到集合中
Integer[] arr2 = {20, 30, 40};
Integer[] arr3 = {50, 60, 70};
List list2 = Arrays.asList(arr2, arr3);
Integer[] integers1 = list2.get(0);
System.out.println(integers1[0]);
int[] arr4 = {20, 30, 40};
//传入的元素为基本类型的数组,也是把数组放到集合中
List ints = Arrays.asList(arr4);
int[] integers2 = ints.get(0);
System.out.println(integers2[0]);
}
}
List集合中的元素有序,就是存入元素和取出元素的顺序一致,并且每一个元素都存在一个索引.元素是可以重复的.List接口是Conllection接口的子接口,那么也就继承了根接口Collection中的方法(也就是可以使用Collection中的各种方法).
package com.xingyun.test;
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
List list = new ArrayList(); //ArrayList为实现类
//在指定索引位置,添加元素。
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add(0, "ddd");
System.out.println(list);
//根据索引来删除元素
list.remove(0);
System.out.println(list);
List list2 = new ArrayList();
list2.add(100);
list2.add(200);
list2.add(200);
list2.add(200);
list2.add(200);
list2.add(300);
list2.add(400);
list2.add(500);
//根据索引获取元素
Object o = list2.get(0);
System.out.println(o);
//修改元素,返回的是修改之前的旧元素。
Object oldEle = list2.set(0, 20000);
System.out.println(list2);
System.out.println(oldEle);
/* int indexOf (Object o)
返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 - 1。
int lastIndexOf (Object o)
返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 - 1。*/
int index = list2.indexOf(200);
System.out.println(index);
int i = list2.lastIndexOf(200);
System.out.println(i);
}
}
List集合中特有一个方法get方法,集合的遍历又出现了新的遍历方式!
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListTest2 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(100);
list.add(200);
list.add(200);
list.add(300);
list.add(400);
list.add(500);
//List 集合的遍历方式
//可以使用父接口中的迭代器
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
System.out.println("===========================");
//for循环
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
System.out.println(o);
}
System.out.println("============================");
//使用子接口List中的迭代器
ListIterator listIterator = list.listIterator();
while (listIterator.hasNext()) {
Object next = listIterator.next();
System.out.println(next);
}
}
}
ArrayList 底层数据结构是数组,查询快,增删慢,线程不安全,效率高.
补:ArrayList集合可以遍历的方法: a.for循环 / b.forEach / c.Collection的迭代器 / d.列表迭代器
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(10);
list.add(50);
list.add(60);
list.add(20);
list.add(30);
list.add(10);
list.add(50);
list.add(60);
list.add(20);
list.add(30);
//subList
List list1 = list.subList(0, 2);
list1.add(600);
System.out.println(list1 +" "); //[10, 50, 600]
//forEach(之前的各种遍历也是可以使用的)
list.forEach(new Consumer() {
@Override
public void accept(Object ele) {
System.out.print(ele+" ");
}
});
//10 50 600 60 20 30 10 50 60 20 30
System.out.println();
//sort
list.sort(new Comparator() {
@Override
public int compare(Object a, Object b) {
Integer x = (Integer) a;
Integer y = (Integer) b;
return -(x - y); //根据返回值的 正 负 0 进行排序
}
});
System.out.print(list+" ");
//[600, 60, 60, 50, 50, 30, 30, 20, 20, 10, 10]
}
}
区别 | 数组 | 集合 |
长度 | 固定的 | 可变的 |
存储对象的类型 | 基本数据类型,引用数据类型 | 引用数据类型 |
元素的种类 | 同一种 | 任意种 |
Vector的底层数据结构是数组,查询快,增删慢,线程安全,效率低
补:Vector集合可以遍历的方法: a.for循环 / b.forEach / c.Collection的迭代器 / d.列表迭代器 / e.Vector集合特有的elements ()
import java.util.Enumeration;
import java.util.Vector;
import java.util.function.Consumer;
public class VectorTest {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add(100); //继承下来的方法
vector.add(100);
//添加元素
vector.addElement(600);
vector.addElement(200);
//插入元素
vector.insertElementAt(400, 0);
//返回第一个和最后面的元素
Object o = vector.get(0);
Object o1 = vector.firstElement();
Object o2 = vector.lastElement();
System.out.println(o);
System.out.println(o1);
System.out.println(o2);
//遍历
//for
for (int i = 0; i < vector.size(); i++) {
Object o3 = vector.get(i);
}
System.out.println("===============================");
//forEach
vector.forEach(new Consumer() {
@Override
public void accept(Object o) {
System.out.println(o);
}
});
System.out.println("==================================");
//elements()
Enumeration elements = vector.elements();
while (elements.hasMoreElements()) {
Object o3 = elements.nextElement();
System.out.println(o3);
}
}
}
LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高
当集合为空时,掉用pop方法会抛异常,而调用poll方法会返回null.唯一的区别就在这,其它功能以及效果都是一样的.
介绍完List的分支,该介绍Set接口分支啦!Set集合中会使用到泛型(很多集合都使用的包括List集合),泛型小编会在新的文章里专门介绍的!
Set集合元素无序且唯一(无序是指存储和取出的顺序不同).
HashSet 底层数据结构是哈希表. HashSet 线程不安全.集合元素可以是 null.哈希表是数组+链表,jdk1.8版本后哈希表优化为数组+链表+红黑树.
元素的唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证唯一性.(Integer以及String类等都已经重写了这两个方法,一定要注意自己定义的类需要重写才能确保唯一性!)
LinkedHashSet集合底层数据结构是哈希表和链表,元素有序且唯一.其中链表保证了元素有序,哈希表保证了元素唯一.且该集合中没有get方法,就不能直接使用for循环.
TreeSet集合底层数据结构是二叉树.元素唯一且可对元素进行排序.一般默认排序是自然排序,也可以用比较器排序.
使用空参构造的都是自然排序.自然排序对元素有要求,要求元素必须实现Comparable 比较接口并且重写 compareTo方法,根据此方法返回值的正负0 来决定元素在树形结构中放置的左右顺序.
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
//1. 自然排序:使用的是空参构造,那就是自然排序,自然排序对元素有要求,
// 要求元素实现 Comparable 比较接口 重写 compareTo方法,根据此方法返回值的正负0 来决定元素在树形结构中放置的左右顺序
//按照年龄进行排序
TreeSet treeSet = new TreeSet<>(); //空参构造
treeSet.add(new Student("张三", 23));
treeSet.add(new Student("李四", 23));
treeSet.add(new Student("刘德华", 21));
treeSet.add(new Student("欧阳震华", 28));
treeSet.add(new Student("刘亦菲", 13));
treeSet.add(new Student("张曼玉", 20));
treeSet.add(new Student("张柏芝", 27));
treeSet.add(new Student("张三", 23));
//这个是新式for循环
for (Student student : treeSet) {
System.out.println(student.getAge() + "===" + student.getName());
}
/*
13===刘亦菲
20===张曼玉
21===刘德华
23===张三
23===李四
27===张柏芝
28===欧阳震华
*/
}
}
public class Student implements Comparable{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//自然排序,Student类已经实现Comparable接口
//重写compareTo方法
@Override
public int compareTo(Student student) {
//先比较年龄
int num=this.age-student.age;
//年龄相等则比较名字
int num2= num==0 ? this.name.compareTo(student.name) : num;
return num2;
}
}
比较器排序使用的是有参构造器.需要自己写一个比较器去实现Comparator接口然后重写compare方法.最后创建Comparator对象,将对象传入到有参构造中.一般这样太麻烦了,可以直接在有参构造器里传入Comparator的匿名对象.通过匿名内部类的样式重写compare方法.
import java.util.Comparator;
import java.util.TreeSet;
public class ComparatorTest {
public static void main(String[] args) {
//比较器排序:采用有参构造
MyComparator myComparator = new MyComparator();
TreeSet treeSet = new TreeSet<>(myComparator); //有参构造
treeSet.add(new Student("张三dddd", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 25));
treeSet.add(new Student("王静", 23));
treeSet.add(new Student("刘德华", 21));
treeSet.add(new Student("欧阳震华adfasdf", 28));
treeSet.add(new Student("刘亦菲ddd", 13));
treeSet.add(new Student("张曼玉ddd", 20));
treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
treeSet.add(new Student("张三asdfas", 23));
for (Student student : treeSet) {
System.out.println(student.getAge() + "===" + student.getName());
}
/*
13===刘亦菲ddd
20===张曼玉ddd
21===刘德华
23===张三asdfas
23===张三dddd
23===王菲
23===王静
25===王菲
27===张柏芝dddddddddddddddddd
28===欧阳震华adfasdf
*/
}
//自己的比较器实现了Comparator接口且重写了compare方法
public static class MyComparator implements Comparator {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2; //根据此方法返回的正负0决定元素排列的左右顺序
}
}
}
直接使用匿名内部类传入这个比较器的对象
import java.util.Comparator;
import java.util.TreeSet;
public class ComparatorTest2 {
public static void main(String[] args) {
//直接使用匿名内部类传入这个比较器的对象。
TreeSet treeSet = new TreeSet<>(new Comparator() {
//匿名内部类
@Override
public int compare(Student s1, Student s2) {
//根据名字长度排序
int num = s1.getName().length() - s2.getName().length();
//名字长度相同则根据名字内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
//都相同的话,根据年龄排序
int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
}
});
treeSet.add(new Student("张三dddd", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 23));
treeSet.add(new Student("王菲", 25));
treeSet.add(new Student("王静", 23));
treeSet.add(new Student("刘德华", 21));
treeSet.add(new Student("欧阳震华adfasdf", 28));
treeSet.add(new Student("刘亦菲ddd", 13));
treeSet.add(new Student("张曼玉ddd", 20));
treeSet.add(new Student("张柏芝dddddddddddddddddd", 27));
treeSet.add(new Student("张三asdfas", 23));
for (Student student : treeSet) {
System.out.println(student.getAge() + "===" + student.getName());
}
/*
23===王菲
25===王菲
23===王静
21===刘德华
13===刘亦菲ddd
23===张三dddd
20===张曼玉ddd
23===张三asdfas
28===欧阳震华adfasdf
27===张柏芝dddddddddddddddddd
*/
}
}
(小编也在努力学习更多哟!以后再慢慢分享的啦!)
希望对友友们有所帮助!!!!