Collection集合
集合是java中的一种容器,可以存储多个数据
数组的长度是固定的,集合的长度是可变的。数组存储的是同一种基本数据类型,集合存储的是对象,而且对象类型可以不一致。
集合按存储结构可以分为两大类:单列集合Collection和双列集合Map。
Collection中常用的方法
boolean add(E e); 添加元素
boolean remove(E e); 删除元素
void clear(); 清空元素
boolean contains(E e); 判断集合中是否包含某个元素
boolean isEmpty(); 判断集合是否为空
int size(); 获取集合的长度
object[] toArray(); 将集合转换成一个数组
Collection<String> coll=new ArrayList<>();
coll.add("good");//添加元素
coll.add("java");
coll.add("nice");
Object[] list1=coll.toArray();//将集合转成数组
System.out.println(list1[2]);
coll.remove("nice");//删除元素
System.out.println(coll);
System.out.println(coll.size());//获取集合的长度
boolean result1=coll.contains("java");//判断元素中是否有java
System.out.println(result1);
boolean result=coll.isEmpty();//判断集合是否为空
System.out.println(result);
coll.clear();//清空集合中的元素
System.out.println(coll);
ArrayList<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list);
int a=list.remove(2);
System.out.println(a);//3
System.out.println(list);//1,2
Iterator迭代器
Collection集合元素的通用获取方式。在取元素之前判断集合中有没有元素,如果有,就把这个元素取出来,继续判断,一直把集合中所有的元素全部取出。
Iterator接口的常用方法:
public E next();返回迭代的下一个元素
public boolean hasNext()如果有元素可以迭代,则返回true。
使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
Collection<String> coll=new ArrayList<>();
coll.add("a");
coll.add("b");
Iterator<String> it=coll.iterator();//创建迭代器
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
}
System.out.println(it.hasNext());//false
增强for循环
作用是用来遍历集合或数组
for(集合或数组的数据类型 变量名:集合/数组名){
System.out.println(变量名);
}
泛型:未知的数据类型,当我们不知道使用什么数据类型的时候就可以用泛型
import java.util.ArrayList;
import java.util.Iterator;
public class FanXing {
public static void main(String[] args) {
new FanXing().method1();
}
public void method1(){
/*
使用泛型
好处:避免了类型转换的异常,存储的是什么,取出的是什么
把运行期异常提升到了编译期
弊端:泛型是什么类型,只能存储什么类型
*/
ArrayList<String> list=new ArrayList<>();
list.add("abc");
//list.add(123);无法存储其它类型的数据
Iterator<String> it= list.iterator();
while (it.hasNext()){
String str=it.next();
System.out.println(str);
}
}
public void method(){
/*
不使用泛型
好处:默认的类型是object类型,可以存储任意类型的数据
弊端:不安全,会引发异常
*/
ArrayList list=new ArrayList();
list.add("abc");
list.add(123);
Iterator it= list.iterator();
while (it.hasNext()){
Object obj=it.next();
System.out.println(obj);
String str=(String)obj;
//因为集合里面有数组所以无法向下转型为String类型,会抛出ClassCastException异常
System.out.println(str);
}
}
}
自定义一个类使用泛型:类名后面加<E>
public class GenericClass<E> {//自定义类使用泛型
private E name;
public GenericClass(){}
public GenericClass(E name) {
this.name = name;
}
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
public class DemoGeneric {
public static void main(String[] args) {
GenericClass<String> gc=new GenericClass<>();
gc.setName("String");
String str=gc.getName();
System.out.println(str);
GenericClass<Integer> gc1=new GenericClass<>();
gc1.setName(123);
int num=gc1.getName();
System.out.println(num);
}
}
自定义一个方法使用泛型: 修饰符 <E> void 方法名(E e){}
public class GenericMethod {
public static void main(String[] args) {
GenericMethod gm = new GenericMethod();
gm.method(123);
gm.method("abc");
}
public <E> void method(E e){
System.out.println(e);
}
}
自定义一个接口使用泛型:修饰符 interface 接口名 <E>
public interface GenericInterface <E>{
public abstract void method(E e);
}
public class InterfaceImpl<O> implements GenericInterface<E>{
@Override
public void method(O o) {
System.out.println(o);
}
}
public class DemoGenericInterface {
public static void main(String[] args) {
InterfaceImpl ii=new InterfaceImpl();
ii.method("abc");
ii.method(123);
InterfaceImpl<String> ii1=new InterfaceImpl<>();
ii1.method("str");
}
}
泛型通配符<?>
只能用来传递参数,不能存储数据。
泛型的上限和下限:
上限:? extends E 泛型只能是E类型的子类/本身
下限:?super E 泛型只能是E类型的父类/本身
import java.util.ArrayList;
import java.util.Iterator;
public class DemoGeneric {
public static void main(String[] args) {
ArrayList<String> list1=new ArrayList<>();
list1.add("abc");
ArrayList<Integer> list2=new ArrayList<>();
list2.add(123);
printArray(list1);
printArray(list2);
ArrayList<Object> list3=new ArrayList<>();
getElement(list1);//String类型不是Number的子类所以报错
getElement(list2);//Integer类型是Number的子类
getElement1(list2);//Integer类型不是Number的父类所以报错
getElement1(list3);//Object类型是Number的父类
}
public static void printArray(ArrayList<?> list){
Iterator<?> it= list.iterator();
while (it.hasNext()){
Object obj=it.next();
System.out.println(obj);
}
}
public static void getElement(ArrayList<? extends Number> list){
System.out.println(list);
}
public static void getElement1(ArrayList<? super Number> list){
System.out.println(list);
}
}
集合
List集合
有序的集合,先进先出,有索引,允许存储重复元素
特有方法:(操作索引的时候一定要防止索引越界)
1 public void add(int index,E element);将指定的元素添加到集合中指定的位置上
2 public E get(int index);返回集合中指定位置的元素
3 public E remove(int index)移除集合中指定位置的元素,返回被移除的元素
4 public E set(int index,E element);用指定元素替换指定位置的元素,返回值是更新前的元素
List<String> list=new ArrayList<>();
list.add("aa");
list.add(0,"bb");//将指定的元素添加到集合中指定的位置上
String str=list.get(0);//返回集合中指定位置的元素
System.out.println(str);//bb
String str1= list.remove(1);//移除集合中指定位置的元素,返回被移除的元素
System.out.println(str1);//aa
String str2=list.set(0,"cc");//用指定元素替换指定位置的元素,返回值是更新前的元素
System.out.println(str2);//bb
System.out.println(list);//cc
}
ArrayList集合
此集合是数组结构,查询快增删慢,常用查询数据遍历数据,是最常用集合
LinkedList集合
此集合是双向链表结构增删快,查询慢。包含大量操作首位元素的方法,不能用多态。
java.util.LinkedList<String> linkedList=new java.util.LinkedList<>();
//添加
linkedList.add("aa");
linkedList.addFirst("bb");//在集合开始插入元素
linkedList.addLast("cc");//在集合末尾开始插入元素等效于add
linkedList.push("dd");//等效于addFirst
System.out.println(linkedList);
//获取
String str=linkedList.getFirst();//获取集合的第一个元素
String str1=linkedList.getLast();//获取集合的最后一个元素
System.out.println(str+"和"+str1);//dd和cc
//删除
String str3=linkedList.removeFirst();//删除集合的第一个元素
//String str5=linkedList.pop();//删除集合的第一个元素等效于removeFirst()
String str4=linkedList.removeLast();//删除集合的最后一个元素
System.out.println(str3+"和"+str4);//dd和cc
System.out.println(linkedList);//[bb, aa]
Vector集合:<了解即可 >
可增长对象数组,Vector的大小可以根据需要增大或缩小,单线程,不同步。addElement方法添加元素
HashSet集合 实现Set接口
不能存储重复元素,没有索引,无法用for循环遍历,可以使用迭代器遍历,无序集合存储和取出元素顺序可能不一致,底层是哈希表结构,查询速度非常快。
不能存储重复元素原理 :使用add方法会调用hashCode方法获取字符串的哈希值,发现有话会调用equals方法对相同元素进行比较返回true就不会把相同的元素存储到集合当中。(前提就是重写hashCode和equals方法)
哈希值:是一个十进制的整数,由系统随机给出(对象的地址值是逻辑地址,是模拟出来的,不是实际数据存储的物理地址)
public native int hashcode();
native:表示该方法调用是本地操作系统方法
哈希表:1.8之前是数据+链表,1.8之后是数据+链表或数组+红黑树
linkHashSet集合:
此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表
所以它里面的元素是有序的。
可变参数:1.5之后
当方法的参数类型已经确定,但是 参数的个数不确定,就可以使用可变参数
注意:一个方法参数只能有一个可变参数,如果方法有多个参数,可变参数要放在参数列表末尾
原理:可变参数的底层是一个数组,可以根据参数个数创建数组来存储传递这些参数。
public static int add(int...arr){
int sum=0;
for(int i:arr){
sum+=i;
}
return sum;
}
Collections集合工具类
public stactic <T> boolean addAll(Collection<T> c.T...elements):往集合中添加一些元素
public static void shuffle(List<?> list)打乱集合顺序
public staric void sort(List<?> list):将集合元素按默认规则排序
public static void sort(List<?> list,new Comparator<? super T>);将集合按指定元素排序
List<String> list=new ArrayList<>();
Collections.addAll(list,"c","a","d","b");//添加多个元素
Collections.sort(list);//对元素排序
System.out.println(list);
Collections.shuffle(list);//打乱元素顺序
System.out.println(list);
demo01();
}
public static void demo01(){
ArrayList<Person> list1=new ArrayList<>();
list1.add(new Person("小明",8));
list1.add(new Person("小红",12));
list1.add(new Person("小刚",10));
System.out.println(list1);
Collections.sort(list1, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});
System.out.println(list1);
}
MAP集合
public interface Map<K,V>
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
特点:1Map集合是一个双列集合,一个元素有两个值(一个key,一个value)
2.Map集合中的元素,key和value的数据类型可以相同,也可以不同
3.Map集合中的元素,key是不允许重复的,value是可以重复的
4.Map集合中的元素,key和value是一一对应的
Map集合常用方法:
public V put(K key,V value)在此映射中关联指定值与指定键。
返回值:v
存储键值对的时候,key不重复v是null
存储键值对的时候,key重复,会使用新的value替换map中重复的value,返回被替换的value
pulic V remove(K key),按键值删除value,有返回值,没有这个键值返回null。
Map<String,String> map=new HashMap<>();
map.put("aa","11");//添加元素
map.put("bb","22");
map.put("cc","33");
String str=map.get("aa");//获取元素
System.out.println(map);//{aa=11, bb=22, cc=33}
System.out.println(str);//11
String str1=map.remove("bb");//删除元素
System.out.println(map);//{aa=11, cc=33}
System.out.println(str1);//22
Map遍历
//map第一种遍历,键找值,keySet方法获取key,通过key找value
Set<Integer> set = map.keySet();
System.out.print("value:");
for (int key : set) {
String s = map.get(key);
if(key==set.size()){
System.out.print(s);
}else {
System.out.print(s+"、");}
}
//map第二种遍历,Map.Entry(k,v)
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
int key = entry.getKey();
String value = entry.getValue();
System.out.println("key:" + key + ",value:" + value);
}
of方法添加元素
List<String> list=List.of("aa","bb","cc");
System.out.println(list);
Map<Integer,String> map=Map.of(1, "aa",2,"bb");
System.out.println(map);