集合
泛型
package com.ff.javaCollection.day1;
import java.util.ArrayList;
/*
泛型:类型参数化,参数化类型,将类型作为参数传入
<一般为任意的单个大写字母,可以有多个>
泛型传入的类型只可以是类类型
如果没有写,默认的是Object
*/
public class TypeDemo<T,E> {
T name;
E color;
public T test(E e) {
return null;
}
public static void main(String[] args) {
TypeDemo<String, Integer> t = new TypeDemo();
t.test(1);
ArrayList arrayList = new ArrayList();
arrayList.add("abd");
arrayList.add(2);
arrayList.add(true);
//typeDemo.clone();在集合中可以存放多种类型的数据,在调用时只会默认调用父类的方法
for (int i = 0; i < arrayList.size(); i++) {
Object obj = arrayList.get(i);
//在具体使用的时候需要向下转型,在向下转型匹配时需要为每一个不同类型都写出instance of方法去匹配,较麻烦,所以引入泛型
if (obj instanceof String) {
String s = (String) obj;
}
if (obj instanceof Integer) {
Integer s1 = (Integer) obj;
}
if (obj instanceof Boolean) {
Boolean s2 = (Boolean) obj;
}
}
}
}
集合的概念
集合:用来装东西的容器
数组也是一种容器,长度一旦给定,不能改变,只可以存储一个类。
java为什么要引入集合类?
1.集合类的长度可变。
2.不同的数据结构,操作方式不同。底层有数组,链表,树和哈希表等来实现。
集合的体系
集合:可以分为单列集合(collection)和双列集合(Map)。
单列集合可以分为可以重复的List和不可以重合的Set。
List可以分为ArrayList(底层是数组实现),Linklist(底层是链表实现)和Vector(底层是数组实现,且线程安全)。
Set可以分为HashSet(底层用hash实现)和TreeSet(底层用红黑树实现)
双列集合Map可以分为HashMap,TreeMap和HashTable
迭代器:Collestions类
图1 集合的体系结构
Collection中定义的方法
实例1:
package com.ff.javaCollection.day1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Predicate;
public class CollectionDemo1 {
/*
集合类中默认可以存放任意类型的数据,建议使用泛型存储同一种类型的数据
*/
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add("a");//,默认在数组末尾插入元素
collection.add("ab");
collection.add("c");
collection.add("abd");
//collection.clear();//清除数组中的所有元素
//collection.remove("a");//移除数组中的第一个元素“a”
collection.removeIf(new Predicate<String>() {//移除满足条件的元素,可以使用泛型
@Override
public boolean test(String o) {
return o.startsWith("ab");
}
});
System.out.println(collection.contains("a"));//判断数组中是否包含元素a
System.out.println(collection.isEmpty());//判断数组是否为空
System.out.println(collection);
//使用流遍历接口collection
collection.stream().forEach((a) -> System.out.println(a));
}
}
实例2:
- 集合转数组
- 数组转集合
- 可变长度的参数
package com.ff.javaCollection.day1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class CollectionDemo2 {
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add("a");
collection.add("ab");
collection.add("c");
collection.add("abd");
//集合转数组
//Object [] o = collection.toArray();
String [] str = (String[]) collection.toArray(new String [collection.size()]);
System.out.println(collection);
//数组转集合
/*int [] a ={1,2,3,1,2};
Collection c= Arrays.asList(a);*/
Collection c = Arrays.asList(1,2,3,4);//返回Collection类型,但是其本质是Arrays$ArraysList的内部类
ArrayList alist = new ArrayList<>(c);//将List类型的集合通过ArraysList构造方法转化为集合
System.out.println(alist.remove(3));//移除索引位置为3 的元素,并返回。
System.out.println(alist);
//System.out.println(c);
test(1,2,3,4,5);
}
//int...b可变长度的参数,本质是一个数组,一个参数列表中只能有一个可变长度的参数并且只可以放在参数类表的末尾。
public static void test (int a,int...b){
System.out.println(a);
System.out.println(Arrays.toString(b));
}
}
List接口
List接口特点:可以存储重复元素,有序的(按照元素存入的先后顺序排列)
ArrayList
底层是数组实现的,查询快,增删慢。扩容后如果没有存满元素,则会造成空间浪费。
创建之初在底层创建一个默认长度为10的数组,当数组内容装满后如果继续添加会扩容为原来的1.5倍。
package com.ff.javaCollection.day1;
import java.util.ArrayList;
import java.util.Comparator;
public class ArrayListDemo {
public static void main(String[] args) {
/*
在创建时有两种方法
1.ArrayList arrayList = new ArrayList();//调用默认的无参构造方法,创建ArrayList对象时并没有实际的创建数组,在第一次添加元素时创建,默认长度为10
2.ArrayList arrayList1 = new ArrayList(5);//调用有参的构造方法,创建ArrayList对象时创建一个指定长度的数组。
当数组中不足以放下元素时调用grow()进行数组扩容
*/
ArrayList<String> arrayList = new ArrayList();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("f");
arrayList.add("d");
arrayList.add("e");
System.out.println(arrayList);
arrayList.remove(3);//删除指定位置的索引
System.out.println(arrayList);
arrayList.remove("c");//根据元素内容索引,没有则返回true
System.out.println(arrayList);
arrayList.remove("f");//根据元素内容索引,没有则返回false
System.out.println(arrayList);
arrayList.get(2);//找出索引位置为3的元素
System.out.println(arrayList);
arrayList.set(2, "A");//替换指定位置上的元素
System.out.println(arrayList);
arrayList.indexOf("a");//找到第一个“a”的元素的索引位置
System.out.println(arrayList);
arrayList.lastIndexOf("A");//找到最后一个“A”的元素的索引位置
arrayList.sort(new Comparator<String>() {//排序,使用匿名内部类定义排序规则
@Override
public int compare(String o1, String o2) {
return 0;
}
});
//使用流的方式遍历
arrayList.forEach((a) -> System.out.println(a));
}
}
实例2:
package com.ff.javaCollection.day1;
import java.util.ArrayList;
public class MyArrayDemo extends ArrayList {
public static void main(String[] args) {
MyArrayDemo a = new MyArrayDemo();
a.add("1");
a.add("2");
a.add("3");
a.add("4");
a.add("5");
System.out.println(a);
a.removeRange(1,3);//此方法为受保护的,因此只可以在子类中访问。删除指定区间,包含前面索引对应的元素,不包括后面索引对应的元素
System.out.println(a);
}
}
实例3:
package com.ff.javaCollection.day1;
import java.util.ArrayList;
public class ArrayListDemo2 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("f");
ArrayList<String> arrayList1 = new ArrayList();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("f");
System.out.println(arrayList.addAll(arrayList1));//将arrayList1中的所有元素加入ArrayList中
System.out.println(arrayList.removeAll(arrayList1));//删除两个集合中的相同的元素,有操作返回true。即求差集
System.out.println(arrayList.retainAll(arrayList1));//保留两个集合中相同的元素,有变化返回true。即求交集
System.out.println(arrayList.containsAll(arrayList1));//前面的集合中是否包含指定集合中的元素,包含则返回true
}
}
实例4:
LiskedList
底层是链表实现的,查询慢,增删快。
元素查找时conf第一个节点向后查找,增加删除元素是其他元素位置不动,只需要改变指针域的值即可。
package com.ff.javaCollection.day1;
import java.util.LinkedList;
public class LinkedListDemo {
//LinkedList查询某个元素从头结点或者尾结点开始查找,所以查询效率低。
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("a");
linkedList.add("b");
linkedList.add("c");
linkedList.add("d");
linkedList.add("e");
System.out.println(linkedList);
System.out.println(linkedList.get(2));
}
}