diff --git a/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/CollectionCommonFunction.java b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/CollectionCommonFunction.java new file mode 100644 index 0000000..d3c7fa6 --- /dev/null +++ b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/CollectionCommonFunction.java @@ -0,0 +1,92 @@ +package com.markilue.java_learning.collection; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * @BelongsProject: java_learning + * @BelongsPackage: com.markilue.java_learning.collection + * @Author: dingjiawen + * @CreateTime: 2022-09-18 14:34 + * @Description: + * TODO collection的addAll,add,retainAll方法: + * 1)addAll(另一个集合)方法会将单个元素都加进去 + * 2)add(另一个集合)方法会将其作为一个整体加入 + * 3)retainAll(另一个集合)方法会将两个集合的交集保留下来,其他的丢弃 =>注意:不是返回一个新集合,而是改变原来的集合 + * @Version: 1.0 + */ +public class CollectionCommonFunction { + + + //addAll + @Test + public void test2(){ + Collection coll = new ArrayList(); + coll.add(1); + coll.add(2); + + System.out.println("coll集合元素的个数:" + coll.size()); //2 + + Collection other = new ArrayList(); + other.add(1); + other.add(2); + other.add(3); + + coll.addAll(other); +// coll.add(other); + System.out.println("coll集合元素的个数:" + coll.size()); //5 + + for (Object o : coll) { + System.out.println(o);// 1 2 1 2 3 + } + } + + //add + @Test + public void test3(){ + Collection coll = new ArrayList(); + coll.add(1); + coll.add(2); + + System.out.println("coll集合元素的个数:" + coll.size()); //2 + + Collection other = new ArrayList(); + other.add(1); + other.add(2); + other.add(3); + + coll.add(other); +// coll.add(other); + System.out.println("coll集合元素的个数:" + coll.size()); //3 + + for (Object o : coll) { + System.out.println(o);// 1 2 [1 2 3] + } + } + + //retainAll + @Test + public void test5(){ + Collection coll = new ArrayList(); + coll.add(1); + coll.add(2); + coll.add(3); + coll.add(4); + coll.add(5); + System.out.println("coll集合元素的个数:" + coll.size());//5 + + Collection other = new ArrayList(); + other.add(1); + other.add(2); + other.add(8); + + coll.retainAll(other);//保留交集 + System.out.println("coll集合元素的个数:" + coll.size());//2 + + for (Object o : coll) { + System.out.println(o); //1 2 + } + } +} diff --git a/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/Iterable.java b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/Iterable.java new file mode 100644 index 0000000..ebb301b --- /dev/null +++ b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/Iterable.java @@ -0,0 +1,110 @@ +package com.markilue.java_learning.collection; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +/** + * @BelongsProject: java_learning + * @BelongsPackage: com.markilue.java_learning.collection + * @Author: dingjiawen + * @CreateTime: 2022-09-18 14:50 + * @Description: + * TODO iterator是一个可迭代接口,collection对象都实现了这个接口(java.util.Iterator) + * 1)其使用方法是:首先通过调用集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。 + * 内部是通过迭代器获取索引实现的:在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。 + * 2)可以通过iterable对collection里的元素进行删除,相比于.remove()方法的好处是通过iterable的方式可以加上条件判断 =>使用方式iterator.remove + * 3)未实现java.util.Iterator的类如果想实现foreach等增强for循环的方式,可以去实现java.lang.Iterable接口,具体方式见MyArrayList类 + * 4)快速失败(fail-fast)机制: 在调用iterator方法获取迭代器操作时调用迭代器自身以外的方法对集合中的结构进行改变,如调用list.add()或remove()方法,否则会报错ConcurrentModificationException。 + * 注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何坚决的保证。快速失败迭代器尽最大努力抛出 `ConcurrentModificationException`。 + * 因此,编写依赖于此异常的程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测 bug + * 实现方式:1)在ArrayList等集合类中都有一个modCount变量。它用来记录集合的结构被修改的次数。 + * 2)当我们给集合添加和删除操作时,会导致modCount++。 + * 3)然后当我们用Iterator迭代器遍历集合时,创建集合迭代器的对象时,用一个变量记录当前集合的modCount。 + * 例如:`int expectedModCount = modCount;`,并且在迭代器每次next()迭代元素时,都要检查 `expectedModCount != modCount`, + * 如果不相等了,那么说明你调用了Iterator迭代器以外的Collection的add,remove等方法,修改了集合的结构,使得modCount++,值变了,就会抛出ConcurrentModificationException。 + * @Version: 1.0 + */ +public class Iterable { + + //测试iterator.remove方法 + @Test + public void test02(){ + Collection coll = new ArrayList<>(); + coll.add("陈琦"); + coll.add("李晨"); + coll.add("邓超"); + coll.add("黄晓明"); + + //删除名字有三个字的 +// coll.remove(o)//无法编写 + + Iterator iterator = coll.iterator(); + while(iterator.hasNext()){ + String element = iterator.next(); + if(element.length()==3){ +// coll.remove(element);//错误的 + iterator.remove(); + } + } + System.out.println(coll); + } + + + //测试继承了java.lang.Iterator的MyArrayList类 + @Test + public void test(){ + MyArrayList my = new MyArrayList(); + my.add("hello"); + my.add("java"); + my.add("world"); + my.add("atguigu"); + my.add("list"); + my.add("data"); + + + for (String string : my) { + System.out.println(string); + } + } + + @Test + public void test01() { + Collection list = new ArrayList<>(); + list.add("hello"); + list.add("java"); + list.add("atguigu"); + list.add("world"); + + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + list.remove(iterator.next()); + } + } + + @Test + public void test03() { + ArrayList list = new ArrayList<>(); + list.add("hello"); + list.add("java"); + list.add("atguigu"); + list.add("world"); + + //以下代码没有发生ConcurrentModificationException异常 + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + String str = iterator.next(); + + if("atguigu".endsWith(str)){ + list.remove(str); + } + } + } + + + +} + diff --git a/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/ListTest.java b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/ListTest.java new file mode 100644 index 0000000..aefa425 --- /dev/null +++ b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/ListTest.java @@ -0,0 +1,88 @@ +package com.markilue.java_learning.collection; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +/** + * @BelongsProject: java_learning + * @BelongsPackage: com.markilue.java_learning.collection + * @Author: dingjiawen + * @CreateTime: 2022-09-18 15:57 + * @Description: + * TODO List的实现类:ArrayList,Vector,LinkedList + * 1)ArrayList: + * 1.数据存储的结构是数组结构。元素增删慢,查找快; + * 2.发生扩容时,ArrayList扩容为原来的1.5倍; + * 3.初始化为长度为0的空数组,之后在添加第一个元素时,再创建长度为10的数组。 + * 2)Vector: + * 1.底层也用的是数组结构,线程安全,效率低; + * 2.发生扩容时,Vector扩容为原来的2倍; + * 3.初始容量默认为10 + * 4.支持Enumeration 迭代器。但是该迭代器不支持快速失败。面对并发的修改,迭代器很快就完全失败 + * 3)LinkedList: + * 1.数据存储的结构是链表结构(双向链表)。方便元素添加、删除的集合。 + * 2.LinkedList还实现了Deque接口。为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。 + * 3.Stack与LinkedList都能作为栈结构,对外表现的功能效果是一样,但是它们的物理结构不同,Stack的物理结构是顺序结构的数组,而LinkedList的物理结构是链式结构的双向链表。我们推荐使用LinkedList。 + * 4.每种方法都存在两种形式:一种形式在操作失败时抛出异常(add,remove,get),另一种形式返回一个特殊值(null 或 false,具体取决于操作)(offer,poll,peek)。 + * + * 4)ListTest 集合额外提供了一个 listIterator() 方法,该方法返回一个 ListIterator 对象, ListIterator 接口继承了 Iterator 接口,提供了专门操作 ListTest 的方法: + * @Version: 1.0 + */ +public class ListTest { + + + //LinkedList作为栈;使用addFirst和removeFirst方法 + @Test + public void test(){ + LinkedList list = new LinkedList<>(); + //入栈 + list.addFirst(1); + list.addFirst(2); + list.addFirst(3); + + //出栈: LIFO(后进先出) + System.out.println(list.removeFirst());//3 + System.out.println(list.removeFirst());//2 + System.out.println(list.removeFirst());//1 + //栈空了,会报异常java.util.NoSuchElementException + System.out.println(list.removeFirst()); + } + + //LinkedList作为队列;使用addLast和pollFirst方法 + @Test + public void test1(){ + LinkedList list = new LinkedList<>(); + //入队 + list.addLast(1); //或者使用offerLast + list.addLast(2); + list.addLast(3); + + //出队, FIFO(先进先出) + System.out.println(list.pollFirst());//1 //或者使用removeFirst + System.out.println(list.pollFirst());//2 + System.out.println(list.pollFirst());//3 + //队空了,返回null + System.out.println(list.pollFirst());//null + } + + + //测试List中的listIterator迭代器方法 + @Test + public void test2(){ + List c = new ArrayList(); + c.add("张三"); + c.add("李四"); + c.add("王五"); + + //从指定位置往前遍历 + ListIterator listIterator = c.listIterator(c.size()); + while(listIterator.hasPrevious()){ + String previous = listIterator.previous(); + System.out.println(previous); + } + } +} diff --git a/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/MyArrayList.java b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/MyArrayList.java new file mode 100644 index 0000000..b8aa4d8 --- /dev/null +++ b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/MyArrayList.java @@ -0,0 +1,57 @@ +package com.markilue.java_learning.collection; + +import java.util.Arrays; +import java.util.Iterator; + +/** + * @BelongsProject: java_learning + * @BelongsPackage: com.markilue.java_learning.collection + * @Author: dingjiawen + * @CreateTime: 2022-09-18 15:13 + * @Description: TODO 测试实现java.lang.Iterator类,实现增强for + * @Version: 1.0 + */ +public class MyArrayList implements java.lang.Iterable { + + private Object[] array; + private int size; + + public MyArrayList() { + array = new Object[5]; + } + + public void add(E e) { + ensureCapacityEnough(); + array[size++] = e; + + } + + public void ensureCapacityEnough() { + if (size >= array.length) { + array = Arrays.copyOf(array, array.length * 2); + } + } + + + @Override + public Iterator iterator() { + return new Iter(); + } + + private class Iter implements Iterator { + int cursor; + + + @Override + public boolean hasNext() { + return cursor <= size; + } + + @Override + public E next() { + return (E) array[cursor++]; + } + } + + +} diff --git a/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/SetTest.java b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/SetTest.java new file mode 100644 index 0000000..9f633c2 --- /dev/null +++ b/Big_data_example/java_learning/src/main/java/com/markilue/java_learning/collection/SetTest.java @@ -0,0 +1,268 @@ +package com.markilue.java_learning.collection; + +import org.junit.Test; + +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.TreeSet; + +/** + * @BelongsProject: java_learning + * @BelongsPackage: com.markilue.java_learning.collection + * @Author: dingjiawen + * @CreateTime: 2022-09-18 16:46 + * @Description: + * TODO Set的三个实现类 HashSet、LinkedHashSet、TreeSet: + * Set接口是Collection的子接口,set接口没有提供额外的方法。但是比`Collection`接口更加严格了。Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。 + * 1)HashSet: + * 1.底层的实现其实是一个java.util.HashMap支持.底层物理实现是一个Hash表 + * 2.HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。因此,存储到HashSet的元素要重写hashCode和equals方法。具体写法可以参照Employee类 + * 2)LinkedHashSet: + * 1.LinkedHashSet是HashSet的子类,它在HashSet的基础上,在结点中增加两个属性before和after维护了结点的前后添加顺序。 + * 2.`java.util.LinkedHashSet`,它是链表和哈希表组合的一个数据存储结构。LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。 + * 3)TreeSet: + * 1.底层结构:里面维护了一个TreeMap,都是基于红黑树实现的 + * 2.特点:不允许重复;实现排序(自然排序或定制排序) + * 如何实现去重:如果使用的是自然排序,则通过调用实现的compareTo方法;如果使用的是定制排序,则通过调用比较器的compare方法 + * 如何实现排序: + * 方式一:自然排序:让待添加的元素类型实现Comparable接口,并重写compareTo方法 + * 方式二:定制排序:创建Set对象时,指定Comparator比较器接口,并实现compare方法 + * @Version: 1.0 + */ +public class SetTest { + + + //测试将重写了hashcode和equal方法的类放入HashSet中 + @Test + public void test() { + HashSet set = new HashSet<>(); + set.add(new Employee("张三", new Employee.MyDate(1990, 1, 1))); + //重复元素无法添加,因为MyDate和Employee重写了hashCode和equals方法 + set.add(new Employee("张三", new Employee.MyDate(1990, 1, 1))); + set.add(new Employee("李四", new Employee.MyDate(1992, 2, 2))); + + for (Employee object : set) { + System.out.println(object); + } + } + + + //测试LinkedHashSet + @Test + public void test1() { + LinkedHashSet set = new LinkedHashSet<>(); + set.add("张三"); + set.add("李四"); + set.add("王五"); + set.add("张三"); + + System.out.println("元素个数:" + set.size()); //3 + for (String name : set) { + System.out.println(name); //张三 李四 王五 + } + } + + + //测试TreeSet的自然排序 + @Test + public void test2() { + + TreeSet set = new TreeSet<>(); + set.add("zhangsan"); //String它实现了java.lang.Comparable接口 + set.add("zisi"); + set.add("wangwu"); + set.add("hangsan"); + + System.out.println("元素个数:" + set.size()); + for (String str : set) { + System.out.println(str); + } + } + + //测试TreeSet的定制排序 + @Test + public void test3() { + + TreeSet set = new TreeSet(new Comparator(){ + @Override + public int compare(Student o1, Student o2) { + return o1.getId() - o2.getId(); + } + }); + set.add(new Student(3,"张三")); + set.add(new Student(1,"李四")); + set.add(new Student(2,"王五")); + set.add(new Student(3,"张三风")); + + System.out.println("元素个数:" + set.size()); //3 + for (Student stu : set) { + System.out.println(stu); //Student [id=1, name=李四];Student [id=2, name=王五];Student [id=3, name=张三] + } + } +} + + +class Employee { + private String name; + private MyDate birthday; + + public Employee(String name, MyDate birthday) { + super(); + this.name = name; + this.birthday = birthday; + } + + public Employee() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public MyDate getBirthday() { + return birthday; + } + + public void setBirthday(MyDate birthday) { + this.birthday = birthday; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((birthday == null) ? 0 : birthday.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Employee other = (Employee) obj; + if (birthday == null) { + if (other.birthday != null) + return false; + } else if (!birthday.equals(other.birthday)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "姓名:" + name + ", 生日:" + birthday; + } + + static class MyDate { + private int year; + private int month; + private int day; + + public MyDate(int year, int month, int day) { + super(); + this.year = year; + this.month = month; + this.day = day; + } + + public MyDate() { + super(); + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public int getMonth() { + return month; + } + + public void setMonth(int month) { + this.month = month; + } + + public int getDay() { + return day; + } + + public void setDay(int day) { + this.day = day; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + day; + result = prime * result + month; + result = prime * result + year; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MyDate other = (MyDate) obj; + if (day != other.day) + return false; + if (month != other.month) + return false; + if (year != other.year) + return false; + return true; + } + + @Override + public String toString() { + return year + "-" + month + "-" + day; + } + } + +} + +class Student{ + private int id; + private String name; + public Student(int id, String name) { + super(); + this.id = id; + this.name = name; + } + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + //......这里省略了name属性的get/set + @Override + public String toString() { + return "Student [id=" + id + ", name=" + name + "]"; + } +} +