Java集合学习速记

2024-04-16 10:58
文章标签 java 学习 集合 速记

本文主要是介绍Java集合学习速记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述:

C++的STL里面专门有一个“集合”就是set;

Java里面也有Set,却只是集合的一种。

Java集合可分为Collection和Map两种体系
->Collection接口: 
    ->Set:元素无序、不可重复的集合
    ->List:元素有序,可重复的集合(可以看成动态数组)
->Map接口:具有映射关系"key-value对"集合(key相当于函数的自变量,value相当于因变量)


Collection接口:

15个重要方法,其中hashCode在后面Set中再详写,然后还有一个涉及泛型以后再说。

package com.mustso.java1;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;import org.junit.Test;/** 1.存储对象可以考虑:①数组②集合* 2.数组存储对象的特点:Student[] stu = new Student[20];stu[0] = new Student();...*     ->弊端:①一旦创建,其长度不可变。②真实的数组存放的对象的个数是不可知的。* 3.集合*      Collection接口*                |-----List接口:存储有序的,可以重复的元素*                           |-----ArrayList、LinkedList、Vector*                |-----Set接口:存储无序的,不可重复的元素*                           |-----HashSet、LinkedHashSet、TreeSet*      Map接口:存储“键-值”对 的数据*           |-----HashMap、LinkedHashMap、TreeMap、Hashtable(子类:Properties)*/
public class TestCollection {@Testpublic void testCollection1(){Collection coll = new ArrayList();//1.size():返回集合中元素的个数System.out.println(coll.size());//0//2.add(Object obj):向集合中添加一个元素coll.add(123);coll.add("AA");coll.add(new Date());coll.add("BB");System.out.println(coll.size());//4//3.addAll(Collection coll):将形参coll中包含的所有元素添加到当前集合中Collection coll1 = Arrays.asList(1,2,3);coll.addAll(coll1);System.out.println(coll.size());//7//查看集合元素System.out.println(coll);//4.isEmpty():System.out.println(coll.isEmpty());//false//5.clear():清空集合元素coll.clear();System.out.println(coll.isEmpty());//true}@Testpublic void testCollection2(){Collection coll = new ArrayList();coll.add(123);coll.add("AA");coll.add(new Date());coll.add("BB");
//		Person p = new Person("MM",23);coll.add(new Person("MM",23));System.out.println(coll);//6.contains(Object obj):判断集合中是否包含指定元素,包含返回true//判断的依据:根据元素所在的类的equals()方法判断//明确:如果存入集合中的元素是自定义类的对象。要求:自定义类要重写equals()方法!boolean b1 = coll.contains("AA");System.out.println(b1);boolean b2 = coll.contains(new Person("MM",23));System.out.println(b2);//7.containsAll(Collection coll):判断当前集合中是否包含coll中所有的元素Collection coll1 = new ArrayList();coll1.add(123);coll1.add("AA");boolean b3 = coll.containsAll(coll1);System.out.println(b3);coll1.add(456);//8.retainAll(Collection coll):求当前集合与coll的共有元素,返回给当前集合coll.retainAll(coll1);System.out.println(coll);//9.remove(Object obj):删除集合中的obj元素,若删除成功返回true否则返回falseboolean b4 = coll.remove("bb");System.out.println(b4);}@Testpublic void testCollection3(){Collection coll = new ArrayList();coll.add(123);coll.add("AA");coll.add(new Date());coll.add("BB");coll.add(new Person("MM",23));Collection coll1 = new ArrayList();coll1.add(123);coll1.add("AA");//10.removeAll(Collection):从当前集合中删除包含在coll中的元素coll.remove(coll1);System.out.println(coll);//11.equals(Object obj):判断两个集合中的所有元素是否完全相同Collection coll2 = new ArrayList();coll2.add(123);coll2.add("AA");System.out.println(coll1.equals(coll2));//12.hashCode():System.out.println(coll.hashCode());//13.toArray():将集合转化为数组Object[] obj = coll.toArray();for (Object object : obj) {System.out.println(object);}System.out.println("----------------------------------");//14.iterator():返回一个Iterator接口实现类的对象,进而实现集合的遍历Iterator iterator = coll.iterator();//方式一:
//		for (int i = 0;i < coll.size();++i){
//			System.out.println(iterator.next());
//		}//方式二:推荐while (iterator.hasNext()){System.out.println(iterator.next());}}
}

运行结果:

testCollection1:



testCollection2:


testCollection3:




ArrayList是List接口下的主要实现类:


package com.mustso.java1;import java.util.ArrayList;
import java.util.List;
import org.junit.Test;public class TestList {/*** ArrayList:List的主要实现类* List中相对于Collection新增的方法:* void add(int index,Object ele):在指定的索引位置添加元素ele* boolean addAll(int index,Collection eles)* Object get(int index):获取指定索引的元素* Object remove(int index):删除指定索引位置的元素* Object set(int index,Object ele):设置指定索引位置的元素为ele* int indexOf(Object obj):返回obj在集合中首次出现的位置,没有的话返回-1* int lastIndexOf(Object obj):返回obj在集合中最后一次出现的位置,没有的话返回-1* List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex结束的左闭右开的一个子list* * List常用的方法:*      ->增(add(Object obj))*      ->删(remove)*      ->改(set(int index,Object obj))*      ->查(get(int index))*      ->插(add(int index,Object ele))*      ->长度(size())* */@Testpublic void testList1(){List list = new ArrayList();list.add(123);list.add(456);list.add(new String("AA"));list.add(new String("GG"));System.out.println(list);list.add(0, 555);//插入到头System.out.println(list);Object obj = list.get(1);//获取的是第二个元素123System.out.println(obj);list.remove(0);//删除头部元素System.out.println(list.get(0));//输出头部元素:123list.set(0, 111);//将头部元素设置为111System.out.println(list.get(0));//输出头部元素:111}@Testpublic void testList2(){List list = new ArrayList();list.add(123);list.add(456);list.add(new String("AA"));list.add(new String("GG"));list.add(456);//注意查找的时候是通过equals()方法比较System.out.println(list.indexOf(456));//1System.out.println(list.lastIndexOf(456));//4System.out.println(list.indexOf(123)==list.lastIndexOf(123));//trueSystem.out.println(list.indexOf(444));//-1System.out.println("-------------------------");System.out.println(list);List list1 = list.subList(0, 3);//复制 [0,3)的内容给list1System.out.println(list1);}
}

testList1()的运行结果:


testList2()的运行结果:


顺便说说LinkedList和Vector

LinkedList的底层是拿链表实现的(而ArrayList底层是拿数组实现的),所以LinkedList方便做插入删除,对于频繁的插入删除操作优选LinkedList

Vector是古老的实现类了,是线程安全的,但是效率不高,基本不用了


HashSet是Set的主要实现类:

为了实现Set中的元素的不可重复性,特别值得强调的是hashCode()

当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值,

此哈希值决定了此对象在Set中的存储位置。若此位置之前没有对象存储,则这个对象直接存储到此位置。

若此位置已有对象存储,再通过equals()方法比较这两个对象是否相同。

如果相同,后一个对象就不能再添加进来。

万一返回false呢,都存储。(不建议如此)

>要求:hashCode()方法要与equals()方法一致。

	@Testpublic void testHashSet(){Set set = new HashSet();set.add(123);set.add(456);set.add(new String("AA"));set.add(new String("AA"));//不会添加进去set.add("BB");set.add(null);Person p1 = new Person("GG",23);Person p2 = new Person("GG",23);System.out.println(p1.equals(p2));set.add(p1);set.add(p2);System.out.println(set.size());System.out.println(set);System.out.println(set.size());}

运行结果:





LinkedHashSet:使用链表维护了一个添加进集合中的顺序。

导致当我们遍历LinkedHashSet元素时是按照添加进去的顺序遍历的!

LinkedHashSet插入性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。

	@Testpublic void testLinkedHashSet(){Set set = new LinkedHashSet();set.add(123);set.add(456);set.add(new String("AA"));set.add(new String("AA"));//不会添加进去set.add("BB");set.add(null);Iterator iterator = set.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}

运行结果:




TreeSet:

1.向TreeSet中添加的元素必须是同一个类的。

2.可以按照添加进集合中的元素的指定的顺序遍历。向String,包装类等默认按照从小到大的顺序遍历。

3.当向TreeSet中添加自定义的对象时,有两种方法:①自然排序②定制排序

4.自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)

在此方法中,指明按照自定义类的哪个属性进行排序。

5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的此属性值相同

但是程序会认为这两个对象相同,进而后一个对象就不能添加进来。

>compareTo()与hashCode()以及equals()三者保持一致!

	@Testpublic void testTreeSet1(){Set set = new TreeSet();
//		set.add(new String("AA"));
//		set.add(new String("AA"));//不会添加进去
//		set.add("BB");
//		set.add("JJ");
//		set.add("GG");
//		set.add("MM");//当Person类没有实现Comparable接口时,当向TreeSet中添加Person对象时,报ClassCastExceptionset.add(new Person("CC",23));set.add(new Person("MM",21));set.add(new Person("GG",25));set.add(new Person("JJ",24));set.add(new Person("KK",20));set.add(new Person("DD",20));for (Object obj : set) {System.out.println(obj);}}
运行结果:



TreeSet的定制排序:

compare()与hashCode()以及equals()三者保持一致!

	@Testpublic void testTreeSet2(){//1.创建一个实现了Comparator接口的类对象Comparator com = new Comparator(){//向TreeSet中添加Customer类的对象,在此compare()方法中//指明是按照Customer的哪个属性排序的。@Overridepublic int compare(Object o1, Object o2) {// TODO Auto-generated method stubif (o1 instanceof Customer && o2 instanceof Customer ){Customer c1 = (Customer)o1;Customer c2 = (Customer)o2;int i =  c1.getId().compareTo(c2.getId());if (i == 0){return c1.getName().compareTo(c2.getName());}return i;}return 0;}};//2.将此对象作为形参传递给TreeSet的构造器中TreeSet set = new TreeSet(com);//3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象set.add(new Customer("AA",1003));set.add(new Customer("BB",1002));set.add(new Customer("GG",1004));set.add(new Customer("CC",1001));set.add(new Customer("DD",1001));for (Object obj : set) {System.out.println(obj);}}




Person的实现:

package com.mustso.java1;public class Person  implements Comparable{private String name;private  Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}public Person(String name, Integer age) {super();this.name = name;this.age = age;}public Person() {super();// TODO Auto-generated constructor stub}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((age == null) ? 0 : age.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic 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 == null) {if (other.age != null)return false;} else if (!age.equals(other.age))return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}/** 当向TreeSet中添加Person类的对象时,依据此方法确定按照哪个属性排序。*/@Overridepublic int compareTo(Object o) {// TODO Auto-generated method stubif (o instanceof Person){Person p = (Person)o;
//			return this.name.compareTo(p.name);
//			return this.age.compareTo(p.age);//按年龄从小到大排
//			return -this.age.compareTo(p.age);//按年龄从大到小排int i = this.age.compareTo(p.age);if (i == 0){return this.name.compareTo(p.name);}else{return i;}}return 0;}
}


Customer的实现:

package com.mustso.java1;public class Customer {private String name;private Integer id;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((id == null) ? 0 : id.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Customer other = (Customer) obj;if (id == null) {if (other.id != null)return false;} else if (!id.equals(other.id))return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}@Overridepublic String toString() {return "Customer [name=" + name + ", id=" + id + "]";}public Customer(String name, Integer id) {super();this.name = name;this.id = id;}public Customer() {super();// TODO Auto-generated constructor stub}
}

TestSet的完整代码:

package com.mustso.java1;import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;import org.junit.Test;/** Collection接口:* 		|--------List接口:* 				|-----ArrayList(主要实现类)* 				|-----LinkedList(对于频繁的插入删除操作)* 				|-----Vector(古老的实现类、线程安全、不常用)* 		|--------Set接口:存储无序的,元素不可重复,Set中常用的方法都是Collection下定义的。* 				|-----HashSet(主要实现类)* 				|-----LinkedHashSet* 				|-----TreeSet*/
public class TestSet{/** TreeSet的定制排序* * compare()与hashCode()以及equals()三者保持一致!*/@Testpublic void testTreeSet2(){//1.创建一个实现了Comparator接口的类对象Comparator com = new Comparator(){//向TreeSet中添加Customer类的对象,在此compare()方法中//指明是按照Customer的哪个属性排序的。@Overridepublic int compare(Object o1, Object o2) {// TODO Auto-generated method stubif (o1 instanceof Customer && o2 instanceof Customer ){Customer c1 = (Customer)o1;Customer c2 = (Customer)o2;int i =  c1.getId().compareTo(c2.getId());if (i == 0){return c1.getName().compareTo(c2.getName());}return i;}return 0;}};//2.将此对象作为形参传递给TreeSet的构造器中TreeSet set = new TreeSet(com);//3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象set.add(new Customer("AA",1003));set.add(new Customer("BB",1002));set.add(new Customer("GG",1004));set.add(new Customer("CC",1001));set.add(new Customer("DD",1001));for (Object obj : set) {System.out.println(obj);}}/** TreeSet:* 1.向TreeSet中添加的元素必须是同一个类的。* 2.可以按照添加进集合中的元素的指定的顺序遍历。向String,包装类等默认按照从小到大的顺序遍历。* 3.当向TreeSet中添加自定义的对象时,有两种方法:①自然排序②定制排序* 4.自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)* 在此方法中,指明按照自定义类的哪个属性进行排序。* 5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的此属性值相同* 但是程序会认为这两个对象相同,进而后一个对象就不能添加进来。* >compareTo()与hashCode()以及equals()三者保持一致!* */@Testpublic void testTreeSet1(){Set set = new TreeSet();
//		set.add(new String("AA"));
//		set.add(new String("AA"));//不会添加进去
//		set.add("BB");
//		set.add("JJ");
//		set.add("GG");
//		set.add("MM");//当Person类没有实现Comparable接口时,当向TreeSet中添加Person对象时,报ClassCastExceptionset.add(new Person("CC",23));set.add(new Person("MM",21));set.add(new Person("GG",25));set.add(new Person("JJ",24));set.add(new Person("KK",20));set.add(new Person("DD",20));for (Object obj : set) {System.out.println(obj);}}/** LinkedHashSet:使用链表维护了一个添加进集合中的顺序。* 导致当我们遍历LinkedHashSet元素时是按照添加进去的顺序遍历的!* * LinkedHashSet插入性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。*/@Testpublic void testLinkedHashSet(){Set set = new LinkedHashSet();set.add(123);set.add(456);set.add(new String("AA"));set.add(new String("AA"));//不会添加进去set.add("BB");set.add(null);Iterator iterator = set.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}/** Set:存储的元素是无序的、不可重复的!* 1.无序性:无序性!=随机性。真正的无序性指的是元素在底层存储的位置无序。* 2.不可重复性:当向Set中添加相同元素时,后面的这个不能添加进去* * 说明:要求添加进Set中的元素所在的类,一定要重写equals()和hashCode()方法*     进而保证Set中元素的不可重复性*     * Set中的元素是如何存储的呢?使用了哈希算法。* 当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值,* 此哈希值决定了此对象在Set中的存储位置。若此位置之前没有对象存储,则这个对象直接存储到此位置。* 若此位置已有对象存储,再通过equals()方法比较这两个对象是否相同。* 如果相同,后一个对象就不能再添加进来。* 万一返回false呢,都存储。(不建议如此)* >要求:hashCode()方法要与equals()方法一致。*/@Testpublic void testHashSet(){Set set = new HashSet();set.add(123);set.add(456);set.add(new String("AA"));set.add(new String("AA"));//不会添加进去set.add("BB");set.add(null);Person p1 = new Person("GG",23);Person p2 = new Person("GG",23);System.out.println(p1.equals(p2));set.add(p1);set.add(p2);System.out.println(set.size());System.out.println(set);System.out.println(set.size());}}

Map:

package com.mustso.java1;import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;import org.junit.Test;
/** Collection接口* * Map接口* 		|-----HashMap:Map的主要实现类* 		|-----LinkedHashMap:使用链表维护添加进Map中的顺序,故遍历Map时是按照添加的顺序遍历的。* 		|-----TreeMap:按照添加进Map中的元素的Key的指定属性进行排序* 						要求:key必须是同一个类的对象* 		|-----Hashtable* 			|-----Properties:*/
public class TestMap {/** Object put(Object key,Object value):向Map中添加一个元素* Object remove(Object key):按照指定的key删除此key-value* void putAll(Map t)* void clear():清空* Object get(Object key):获取指定key的value值.若无此key,返回null* boolean containsKey(Object key):判断是否存在此key* boolean containsValue(Object value):判断是否存在此value* int size():返回集合的长度* boolean isEmpty()* boolean equals(Object obj)* * HashMap:* 1.Key是用Set来存放的,不可重复。Value是用Collection存放的,可重复* 一个key-value对,是一个Entry。所有的Entry是用Set存放的,也是不可重复的。* 2.向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同。* 若相同,则只添加后添加的那个元素。*/@Test public void test1(){Map map = new HashMap();map.put("AA", 123);map.put("BB", 456);map.put("BB", 456);map.put(123, "cc");map.put(123, "dd");//将会取代上面一个map.put(null, null);System.out.println(map.size());System.out.println(map);map.remove("BB");System.out.println(map);Object value1 = map.get(123);System.out.println(value1);Object value2 = map.get(1234);//nullSystem.out.println(value2);}/** 如何遍历Map* Set keySet()* Collection values()* Set entrySet()*/@Test public void test2(){Map map = new HashMap();map.put("AA", 123);map.put("BB", 456);map.put(123, "cc");map.put(null, null);map.put(new Person("GG",27), 23);//1.遍历key集Set set = map.keySet();for (Object object : set) {System.out.println(object);}System.out.println();//2.遍历value集Collection values = map.values();for (Object object : set) {System.out.println(object);}System.out.println();//3.如何遍历key-value对Set set1 = map.entrySet();for (Object object : set1) {System.out.println(object);}
//		Set set1 = map.keySet();
//		for (Object object : set1) {
//			System.out.println(object + "--->"+map.get(object));
//		}}@Test public void test3(){Map map = new LinkedHashMap();map.put("AA", 123);map.put("BB", 456);map.put(123, "cc");map.put(null, null);map.put(new Person("GG",27), 23);Set set = map.entrySet();for (Object object : set) {System.out.println(object);}}@Testpublic void test4(){Map map = new TreeMap();map.put(new Person("AA",23), 89);map.put(new Person("MM",22), 79);map.put(new Person("GG",33), 69);map.put(new Person("JJ",13), 99);Set set = map.keySet();for (Object object : set) {System.out.println(object);}}
}



这篇关于Java集合学习速记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/908603

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06