Java集合笔记

作者:@冰山醉酒
本文为作者原创,转载请注明出处:https://www.cnblogs.com/douFrank/p/16117958.html


1|0集合

一:集合概念

对象的容器,实现了对对象常用的操作,类似数组的功能

二:集合和数组的区别:

  1. 数组的长度固定,集合查长度不固定

  2. 数组可以存储基本类型和引用类型,而集合只能存储引用类型

位置:java.util.*

2|0Collection体系集合

特点:代表一组任意类型的对象,无序,无下标,不能重复

方法:

 

方法:add( ), remove( ),contains( ),isEmpty( )

collection是抽象类,不能直接new,

Collecttion collection = new ArrayList(); //遍历元素时,因为对象那个没有下标 //1,增强for for (Object object : collection){ Student student = (Student)object; System.out.println(student.toString()); } //2,使用迭代器 Iterator iterator = collection.iterator(); while (iterator.hasNext()){ Student student1 = (Student) iterator.next(); System.out.println(student1.toString()); }

3|0ArrayList

ArrayList使用:

1 //创建集合 2 ArrayList al = new ArrayList(); 3 //1,增加 4 Student s1 = new Student("小明",12); 5 al.add(s1); 6 //2,删除 7 al.remove(new Student("小明",12));//会调用equals()方法 8 //3,遍历(重点) 9 //for循环 10 for (int i = 0; i < al.size(); i++) { 11 System.out.println(al.get(i)); 12 } 13 //增强for 14 for (Object object : 15 al) { 16 System.out.println(object); 17 } 18 19 //使用迭代器 20 Iterator it = al.iterator(); 21 while (it.hasNext()){ 22 System.out.println(it.next()); 23 } 24 //使用list迭代器(可向后遍历,也可向前遍历) 25 ListIterator lt = al.listIterator(); 26 while(lt.hasNext()){ 27 System.out.println(lt.next()); 28 } 29 30 while(lt.hasPrevious()){ 31 System.out.println(lt.previous()); 32 } 33 //4,判断 34 System.out.println(al.contains(new Student("小鸟",19))); 35 //5,查找 36 System.out.println(al.indexOf(new Student("小红",13))); 37

源码分析: DEFAULT_CAPACITY = 10默认容量

注意:如果没有像集合中添加任何元素,容量0,添加一个元素之后,容量10,每次孔融时原来的1.5倍

size实际元素的个数

add()添加元素

public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }

4|0LinkList

使用同ArrayList一致

5|0Vector

使用同ArrayList一致,但遍历不同,并且有自己独有方法

//遍历 //使用枚举器 Enumeration elements = vector.elements(); while (elements.hasMoreElements()){ String o = (String)elements.nextElement(); System.out.println(o); } //其他方法 //firstElement、lastElement、elementAt(int index)根据下标返回

6|0泛型

Java的泛型是JDK1.5引入的一个新特性,其本质是参数化类型,把类型作为参数传递

常见的形式有泛型类,泛型接口,泛型方法

好处:提高代码的重用性,防止类型转换异常,提供代码的安全性

泛型类

public class MyGeneric<T> { //使用泛型T //1 创建变量 public T t; //2 泛型作为方法的变量 public void show(T t){ // T t1 = new T();泵使用new 的方式,因为T的类型并不确定 System.out.println(t); } //3泛型作为方法的返回值 public T getT(){ return t; } }

泛型接口

public interface MyInterface<T> { String name = "张三"; T serve(T t); } //接口实现 public class MyInterfaceImpl implements MyInterface<String> { @Override public String serve(String s) { System.out.println(s); return s; } } public class MyInterfactImpl2<T> implements MyInterface<T> { @Override public T serve(T t) { System.out.println(t); return t; }

泛型方法

public class MyGenericMethod { //泛型方法 public <T> void show(T t){ System.out.println(t); } public <T> T set(T t){ return t; } }

泛型集合:参数化类型、类型安全的集合强制类型元素必须一致。特点:编译时即可检查,而非运行时抛出异常,访问时,不必类型转换。不同泛型之间不能相互赋值反省不存在多态

ArrayList<String> arrayList = new ArrayList<>();

调用以上泛型类,泛型接口,泛型方法

//使用泛型创建对象 //注意:1泛型只能使用引用对象 2,不同泛型对象不也能相互复制 //泛型对象 MyGeneric<String> myGeneric = new MyGeneric<String>(); myGeneric.t = "hello"; myGeneric.show("大家好"); String string = myGeneric.getT(); MyGeneric<Integer> myGeneric1 = new MyGeneric<>(); myGeneric1.t = 2000; myGeneric1.show(30); Integer t = myGeneric1.getT(); //泛型接口 //MyGeneric<String> myGeneric2 = myGeneric1;出现错误,不同泛型对象 MyInterfaceImpl impl = new MyInterfaceImpl(); impl.serve("XXXXXXX"); MyInterfactImpl2<Integer> impl2 = new MyInterfactImpl2<>(); impl2.serve(200); //泛型方法 MyGenericMethod myGenericMethod = new MyGenericMethod(); //三种方式都可以,给什么变成什么 myGenericMethod.show("中国加油"); myGenericMethod.show(200); myGenericMethod.show(3.14); }

7|0Set

Hashset:基于HashCode计算与元素存放位置,当存入元素的哈希码相同时,会调用equals进行确认,如果为true,就拒绝后者存入。

TreeSet:基于排列顺序实现元素不重复。实现了SortedSet接口,对集合元素自动排序。元素对象的类型必须实现Comparable接口,指定排列顺序。

8|0Map集合

 

 

Map接口的特点:1. 用于存储任意键值对(key-value)

  1. 键:无序,无下标,不允许重复(唯一)

  2. 值:无序,无下标,允许重复

9|0HashMap

使用

//创建对象 HashMap<Student,String> hashMap = new HashMap<>(); //添加元素 Student s1 = new Student("熏悟空",100); hashMap.put(s1,"上海"); //删除元素 hashMap.remove(s1); //遍历 //1,增强for key.Set() for (Student key: hashMap.keySet() ) { System.out.println(key.toString()+"=="+hashMap.get(key)); } //2,增强for entrySet() for (Map.Entry entry : hashMap.entrySet()) { System.out.println(entry.getKey()+"=="+entry.getValue()); } //判断 System.out.println(hashMap.containsKey(s1)); System.out.println(hashMap.containsValue("曹县"));

源码分析

(1)HashMap刚创建时,table时null,为了节省空间,当添加第一个原始时,table容量调整为16
(2)当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为的2倍,目的是减少调整元素的个数
(3)jdk1.8当每个链长度大于8,并且元素个数大于等于64时,会调整为红黑树,谜底提高执行效率
(4)jdk1.8当链表长度小于6时,会调整为链表
(5)jdk1.8以前,链表时头插入,jdk1.8以后是尾插入

注意:HashMap与HashSet关系,其实是同一个东西,都是HashMap

//hashMap.put(s1,"炮楼");加不上
//hashMap.put(new Student("熏悟空",100),"炮楼");加上了
//如果不想让其加入,“去重”。重写HashCode()和equals()
//删除也是同一个道理

10|0TreeMap

方法:同HashMap一致

注意:因为Tree Map的存储结构为红黑树,添加元素的时候需要进行比较

//方法1:使用Comparator定制比较 TreeMap<Student,String> treeMap = new TreeMap<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int n1 = o1.getStuDo()- o2.getStuDo(); int n2 = o1.getName().compareTo(o2.getName()); return n1 == 0 ? n2 : n1; } }); //方法2:在student类中继承Comparable,重写compareTo public class Student implements Comparable<Student>{ @Override public int compareTo(Person o) { int n1 = this.name.compareTo(o.getName()); int n2 = this.age-o.getAge(); return n1==0 ? n2 : n1; } 

11|0Collections 工具类

方法:

ArrayList<Integer> list = new ArrayList<>(); Collections.sort(list); int i = Collections.binarySearch(list,26);//如果查找不到,返回一个负值 Collections.copy(dest,list); Collections.reverse(list); Collections.shuffle(list); Integer[] arr = list.toArray(new Integer[0]); List<String> list2 = Arrays.asList(name2);
  1. sort排序

  2. binarySearch二分查找,若找到返回下标,找不到返回负值

  3. copy(目标,源)复制 复制之前保证目标有自购的容量

  4. resverse反转

  5. shuffle打乱

  6. toArray(new Integer[0]) list转为数组

  7. asList(数组名) 数组转成集合

 

12|0集合总结

集合的概念:对象的容器,和数组类似,定义了对多个对象进行操作的常用方法

List集合:有序、有下标、元素可以重复。(ArrayList【存储结构:数组】,LinkedList【存储结构:双向链表】,vector【存储结构:数组】)

Set集合:无序,无下标,元素不可重复。(HashSet【存储结构:数组+链表+红黑树】、TreeSet【存储结构:红黑树】)

Map集合:存储一对数据,无序,无下标,键不可重复,值可以重复(HashMap【存储结构:数组+链表+红黑树】、HashTable【已过时】、TreeMap【存储结构:红黑树】)

注意: 1. TreeSet和TreeMap因为存储结构是红黑树的原因,添加元素的时候需要比较大小后进行加入,所以当为某些类的对象时候需要继承Comparable接口,重写CompareTo( )方法或者在创建对象时使用Comparator方式进行定制比较

// 使用Comparator 匿名内部类,进行定制比较 TreeSet<Person> treeSet1 = new TreeSet<>(new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { int n1= o1.getAge()- o2.getAge(); int n2 = o1.getName().compareTo(o2.getName()); return n1==0 ? n1 :n2; } });
  1. HashMap与HashSet关系,其实是同一个东西,都是HashMap,同样TreeMap与TreeSet也是同一个东西,都是TreeMap。

  2. Student s3 = new Student("刷和尚",249); hashMap.put(s3,"北京"); //hashMap.put(s3,"炮楼");加不上 //hashMap.put(new Student("刷和尚",249),"炮楼");加上了 //如果不想让其加入,“去重”。重写HashCode()和equals()

     

Collections:集合工具类,定义了除了存储之外的集合常用方法。


__EOF__

本文作者冰山醉酒
本文链接https://www.cnblogs.com/douFrank/p/16117958.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   冰山醉酒  阅读(132)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示