
1 import java.util.ArrayList; 2 import java.util.List; 3 4 /** 5 * Collection接口:用于储存单个对象的集合 6 * List接口: 7 * 1.有序的 8 * 2.允许多个null元素 9 * 3.具体的实现有常用的:ArrayList Vector LinkedList 10 * Set接口: 11 * 12 */ 13 14 15 public class ListDemo { 16 private static void arrayList(){ 17 //使用集合来存储多个不同类型的元素(对象),那么在处理时会比较麻烦,实际开发中,不建议 18 //这样使用,我们应该在一个集合中存储相同的类型对象 19 List<String> list = new ArrayList<>(); 20 list.add("苍老师"); 21 list.add("李老师"); 22 list.add("张老师"); 23 list.add("毕老师"); 24 //list.add(10); 25 26 //遍历集合 27 int size = list.size(); 28 for (int i = 0; i < size; i++) { 29 System.out.println(list.get(i)); 30 } 31 System.out.println(list.contains("苍老师")); 32 } 33 34 public static void main(String[] args) { 35 36 } 37 38 }

1 package com.vince; 2 3 import java.util.HashSet; 4 import java.util.LinkedHashSet; 5 import java.util.Set; 6 import java.util.TreeSet; 7 8 /** 9 * Set接口 10 * 1、无序的(不保证顺序) 11 * 2、不允许重复元素 12 * HashSet、TreeSet、LinkedHashSet 13 * 14 * 如果要排序,选择treeSet 15 * 如果不要排序,也不用保正顺序选择HashSet 16 * 不要排序,要保正顺序,选择LinkedHashSet 17 * @author vince 18 * @description 19 */ 20 public class SetDemo { 21 22 /** 23 * 哈希表和链接列表实现, 24 * 维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。 25 */ 26 private static void linkedHashSet(){ 27 LinkedHashSet<Cat> set = new LinkedHashSet<>(); 28 Cat c1 = new Cat("miaomiao",5,1); 29 Cat c2 = new Cat("huahua",2,2); 30 Cat c3 = new Cat("tom",5,3); 31 Cat c4 = new Cat("miaomiao",3,1); 32 set.add(c1); 33 set.add(c2); 34 set.add(c3); 35 set.add(c4); 36 37 for(Cat c: set){ 38 System.out.println(c); 39 } 40 } 41 42 /** 43 * 有序的,基于TreeMap(二叉树数据结构),对象需要比较大小,通过对象比较器来实现, 44 * 对象比较器还可以用来去除重复元素,如果自定义的数据类,没有实现比较器接口,将无法添加到TreeSet集合中。 45 * 46 */ 47 private static void treeSet(){ 48 TreeSet<Cat> tree = new TreeSet<>(new CatComparator()); 49 Cat c1 = new Cat("miaomiao",5,1); 50 Cat c2 = new Cat("huahua",2,2); 51 Cat c3 = new Cat("tom",5,3); 52 Cat c4 = new Cat("miaomiao",3,1); 53 tree.add(c1); 54 tree.add(c2); 55 tree.add(c3); 56 tree.add(c4); 57 System.out.println(tree.size()); 58 59 for(Cat c: tree){ 60 System.out.println(c); 61 } 62 63 64 65 66 } 67 /** 68 * HashSet 69 * 1、实现原理,基于哈希表(HashMap)实现 70 * 2、不允许重复,可以有一个NULL元素 71 * 3、不保证顺序恒久不变 72 * 4、添加元素时把元素作为HashMap的key存储,HashMap的value使用一个固定的object对象 73 * 5、排除重复元素是通过equals来检查对象是否相同 74 * 6、判断两个对象是否相同,先判断两个对象的hashCode是否相同(如果两个对象的hashCode相同,不一定是同一个对象,如果不同,那一定不是 75 * 同一个对象),如果不同,则两个对象不是同一个对象,如果相同,还要进行equals判断,equals相同则是同一个对象,不同则不是同一个对比象。 76 * 7、自定义对象要认为属性值都相同时为同一个对象,有这种需求时,那么我们要重写对象所在类的hashCode和equals方法。 77 * 78 * 小结 79 * (1)哈希表的存储结构:数组+链表,数组里的每个元素以链表的形式存储 80 * (2)如何把对象存储到哈希表中,先计算对象的hashCode值,再对数组的长度求余数,来决定对象要存储在数组中的哪个位置 81 * (3)解决hashSet中的重复值使用的方式是,参考第6点 82 */ 83 private static void hashSet(){ 84 Set<String> set = new HashSet<>(); 85 set.add("飞飞"); 86 set.add("备备"); 87 set.add("亮亮"); 88 set.add("关关"); 89 set.add("曹操"); 90 set.add("亮亮"); 91 System.out.println(set.size()); 92 String[] names = set.toArray(new String[]{}); 93 for(String s: names){ 94 System.out.println(s); 95 } 96 97 Cat c1 = new Cat("miaomiao",5,1); 98 Cat c2 = new Cat("huahua",2,2); 99 Cat c3 = new Cat("tom",5,3); 100 Cat c4 = new Cat("miaomiao",5,1); 101 Set<Cat> cats = new HashSet<>(); 102 cats.add(c1); 103 cats.add(c2); 104 cats.add(c3); 105 cats.add(c4); 106 //cats.add(c1); 107 System.out.println(cats.size()); 108 109 for(Cat c: cats){ 110 System.out.println(c); 111 } 112 System.out.println("c1="+c1.hashCode()); 113 System.out.println("c2="+c2.hashCode()); 114 System.out.println("c3="+c3.hashCode()); 115 System.out.println("c4="+c4.hashCode()); 116 } 117 118 public static void main(String[] args) { 119 // hashSet(); 120 // treeSet(); 121 linkedHashSet(); 122 } 123 124 }

1 package com.vince; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.Collection; 6 import java.util.Enumeration; 7 import java.util.Iterator; 8 import java.util.List; 9 import java.util.Vector; 10 import java.util.function.Function; 11 import java.util.function.Predicate; 12 import java.util.function.Supplier; 13 14 /** 15 * 集合的输出(迭代) 16 * @author vince 17 * @description 18 */ 19 public class IteratorDemo { 20 21 22 //断言接口 23 private static void predicateTest(){ 24 List<String> list = Arrays.asList("Larry", "Moe", "Curly","Tom","QF_vince"); 25 List<String> result = filter(list,(s)->s.contains("o")); 26 result.forEach(System.out::println); 27 } 28 29 private static List<String> filter(List<String> list,Predicate<String> p){ 30 List<String> results = new ArrayList<>(); 31 32 for (String s : list) { 33 if(p.test(s)){ //测试是否符合要求 34 results.add(s); 35 } 36 } 37 38 return results; 39 } 40 41 //Supplier 代表结果供应商 42 private static void supplierTest(){ 43 List<Integer> list = getNums(10,()->(int)(Math.random() * 100)); 44 list.forEach(System.out::println); 45 } 46 47 private static List<Integer> getNums(int num,Supplier<Integer> sup){ 48 List<Integer> list = new ArrayList<>(); 49 for(int i=0;i<num;i++){ 50 list.add(sup.get()); 51 } 52 return list; 53 } 54 55 //表示接受一个参数并产生结果的函数 56 private static void functionTest(){ 57 String s = strToUpp("qf_vince",(str)->str.toUpperCase()); 58 System.out.println(s); 59 } 60 61 public static String strToUpp(String str,Function<String,String> f){ 62 return f.apply(str); 63 } 64 65 66 /** 67 * JDK1.8新的迭代方法 68 */ 69 private static void foreach(){ 70 List<String> list = new ArrayList<>(); 71 list.add("tom"); 72 list.add("jack"); 73 list.add("job"); 74 list.add("lily"); 75 76 //Consumer 77 list.forEach(s->System.out.println(s)); 78 //list.forEach(System.out::println); 79 } 80 81 private static void enumeration(){ 82 Vector<String> vs = new Vector<>(); 83 vs.add("tom"); 84 vs.add("jack"); 85 vs.add("job"); 86 vs.add("lily"); 87 88 Enumeration<String> es = vs.elements(); 89 while(es.hasMoreElements()){ 90 System.out.println(es.nextElement()); 91 } 92 } 93 94 //foreach(1.5后) 95 private static void foreach(Collection<Cat> c){ 96 for(Cat cat: c){ 97 System.out.println(cat); 98 } 99 } 100 101 //iterator(1.5之前统一的迭代集合方式) 102 private static void iterator(Collection<Cat> c){ 103 Iterator<Cat> iter = c.iterator(); 104 while(iter.hasNext()){ 105 System.out.println(iter.next()); 106 } 107 } 108 109 public static void main(String[] args) { 110 List<Cat> list = new ArrayList<>(); 111 Cat c1 = new Cat("miaomiao",5,1); 112 Cat c2 = new Cat("huahua",2,2); 113 Cat c3 = new Cat("tom",5,3); 114 Cat c4 = new Cat("miaomiao",3,1); 115 list.add(c1); 116 list.add(c2); 117 list.add(c3); 118 list.add(c4); 119 // iterator(list); 120 // foreach(list); 121 122 // enumeration(); 123 // foreach(); 124 // functionTest(); 125 // supplierTest(); 126 predicateTest(); 127 128 } 129 130 }

1 package com.vince; 2 3 import java.util.Collection; 4 import java.util.HashMap; 5 import java.util.Hashtable; 6 import java.util.LinkedHashMap; 7 import java.util.Map; 8 import java.util.Map.Entry; 9 import java.util.Set; 10 import java.util.TreeMap; 11 12 /** 13 * Map接口: 14 * 1、键值对存储一组对象 15 * 2、Key不能重复(唯一),Value可以重复 16 * 3、具体的实现类:HashMap TreeMap Hashtable LinkedHashMap 17 * 4、HashMap 与 Hashtable的区别? 18 * 19 * 5、如何选择使用哪个? 20 * 21 * 6、数据结构:数组、链表、二叉树(红黑树)、哈希表(数组+链表)、栈、队列 22 * @author vince 23 * @description 24 */ 25 public class MapDemo { 26 27 /** 28 * 基于二叉树的红黑树实现 29 */ 30 private static void treeMap(){ 31 Map<String,String> map = new TreeMap<>(); 32 // map.put("one", "Lily"); 33 // map.put("two", "Tom"); 34 // map.put("three", "Bin"); 35 // map.forEach((key,value)->System.out.println(key+"->"+value)); 36 // 37 Map<Dog,String> dogs = new TreeMap<>(); 38 dogs.put(new Dog(1,"2ha",3), "dog1"); 39 dogs.put(new Dog(1,"wangwang",2), "dog2"); 40 dogs.put(new Dog(3,"hsq",4), "dog3"); 41 dogs.forEach((key,value)->System.out.println(key+"->"+value)); 42 } 43 44 /** 45 * LinkedHashMap是HashMap的子类,由于HashMap不能保正顺序恒久不变,此类使用一个双重链表来维护 46 * 元素添加的顺序。 47 */ 48 private static void linkedHashMap(){ 49 Map<String,String> table = new LinkedHashMap<>(); 50 table.put("one", "Lily"); 51 table.put("two", "Tom"); 52 table.put("three", "Bin"); 53 table.forEach((key,value)->System.out.println(key+"->"+value)); 54 } 55 56 /** 57 * JDK1.0开始 58 * 基于哈希表实现(数组+链表) 59 * 默认数组大小为11,加载因子0.75 60 * 扩充方式:原数组大小<<1 (*2) +1 61 * 线程安全的,用在多线程访问时 62 */ 63 private static void hashtable(){ 64 65 Map<String,String> table = new Hashtable<>(); 66 table.put("one", "Lily"); 67 table.put("two", "Tom"); 68 table.put("three", "Bin"); 69 70 table.forEach((key,value)->System.out.println(key+"->"+value)); 71 } 72 /** 73 * HashMap的现实原理: 74 * 1、基于哈希表(数组+链表+二叉树(红黑树) )1.8JDK 75 * 2、默认加载因子为0.75,默认数组大小是16, 76 * 3、把对象存储到哈希表中,如何存储? 77 * 把key对象通过hash()方法计算hash值,然后用这个hash值对数组长度取余数(默认16),来决定该对KEY对象 78 * 在数组中存储的位置 ,当这个位置 有多个对象时,以链表结构存储,JDK1.8后,当链表长度大于8时,链表将转换为 79 * 红黑树结构存储。 80 * 这样的目的,是为了取值更快,存储的数据量越大,性能的表现越明显 81 * 82 * 4、扩充原理:当数组的容量超过了75%,那么表示该数组需要扩充,如何扩充? 83 * 扩充的算法是:当前数组容量<<1 (相当于是乘2),扩大1倍, 扩充次数过多,会影响性能,每次扩充表示哈希表重新 84 * 散列(重新计算每个对象的存储位置),我们在开发中尽量要减少扩充次数带来的性能问题。 85 * 5、线程不安全,适合在单线程中使用 86 */ 87 private static void hashMap(){ 88 Map<Integer,String> map = new HashMap<>(); 89 map.put(1, "Tom"); 90 map.put(2, "Jack"); 91 map.put(3, "Vince"); 92 map.put(4, "Bin"); 93 map.put(5, "Lily"); 94 95 System.out.println("size="+map.size()); 96 //从MAP中取值 97 System.out.println(map.get(1));//通过key取value 98 99 //map的遍历 1 遍历Entry 100 Set<Entry<Integer,String>> entrySet = map.entrySet(); 101 for(Entry e: entrySet){ 102 System.out.println(e.getKey()+"->"+e.getValue()); 103 } 104 System.out.println("--------"); 105 //2 遍历键 106 Set<Integer> keys = map.keySet(); 107 for(Integer i: keys){ 108 String value = map.get(i); 109 System.out.println(i+"->"+value); 110 } 111 System.out.println("--------"); 112 //3 遍历值 113 Collection<String> values = map.values(); 114 for(String value: values){ 115 System.out.println(value); 116 } 117 System.out.println("--------"); 118 //4 foreach 119 map.forEach((key,value)->System.out.println(key+"->"+value)); 120 121 System.out.println(map.containsKey(7)); 122 123 //hash 124 Integer key = 1434; 125 126 System.out.println( 1434 % 16 ); 127 128 } 129 130 public static void main(String[] args) { 131 // hashMap(); 132 // hashtable(); 133 treeMap(); 134 } 135 136 }
1 package com.vince; 2 3 import java.util.Optional; 4 5 /** 6 * Optional JDK1.8容器类 7 * @author vince 8 * @description 9 */ 10 public class OptionalDemo { 11 12 public static void main(String[] args) { 13 //创建Optional对象的方式 14 Optional<String> optional = Optional.of("bin"); 15 // Optional<String> optional2 = Optional.ofNullable("bin"); 16 Optional<String> optional3 = Optional.empty(); 17 18 System.out.println(optional.isPresent()); 19 System.out.println(optional.get()); 20 21 optional.ifPresent((value)->System.out.println(value)); 22 23 System.out.println(optional.orElse("无值")); 24 25 System.out.println(optional.orElseGet(()->"default")); 26 27 // try { 28 // optional3.orElseThrow(Exception::new); 29 // } catch (Exception e) { 30 // e.printStackTrace(); 31 // } 32 33 Optional<String> optional4 = optional.map((value)->value.toUpperCase()); 34 System.out.println(optional4.orElse("no found")); 35 36 optional4 = optional.flatMap((value)->Optional.of(value.toUpperCase()+"-flatMap")); 37 System.out.println(optional4.orElse("no found")); 38 39 optional4 = optional.filter((value)->value.length()>3); 40 System.out.println(optional4.orElse("这个值的长度小于3")); 41 } 42 }
package com.vince; import java.util.Deque; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; /** * Queue接口:队列,是一种先进先出的线性数据结构(排队) * LinkedList类实现了queue接口 * 请求队列,消息队列,任务 * * Deque接口:双端队列 * Stack:堆栈 :先进后出 * @author vince * @description */ public class QueueDequeDemo { private static void stack(){ Stack<String> s = new Stack<>(); //压栈 s.push("Bin"); s.push("Tom"); s.push("Lily"); System.out.println(s.pop()); System.out.println(s.pop()); System.out.println(s.pop()); } private static void deque(){ Deque<String> deque = new LinkedList<>(); deque.add("小花"); deque.add("小黑"); deque.add("小小"); deque.add("小白"); deque.add("小丽"); System.out.println(deque.getFirst()); System.out.println(deque.getLast()); } private static void queue(){ Queue<String> queue = new LinkedList<>(); queue.add("小花"); queue.add("小黑"); queue.add("小小"); queue.add("小白"); queue.add("小丽"); System.out.println(queue.size()); System.out.println(queue.peek()); System.out.println(queue.size()); System.out.println(queue.poll()); System.out.println(queue.size()); } public static void main(String[] args) { // queue(); // deque(); stack(); } }
一对多关系:

1 package com.vince; 2 3 import java.util.HashSet; 4 5 //一个老师对应多个学生; 6 public class Teacher { 7 8 private String name; 9 private int age; 10 private String sex; 11 //因为一对多,所以学生要设置集合 12 private HashSet<Student> students = new HashSet<>(); 13 14 15 public HashSet<Student> getStudents() { 16 return students; 17 } 18 public void setStudents(HashSet<Student> students) { 19 this.students = students; 20 } 21 public String getName() { 22 return name; 23 } 24 public void setName(String name) { 25 this.name = name; 26 } 27 public int getAge() { 28 return age; 29 } 30 public void setAge(int age) { 31 this.age = age; 32 } 33 public String getSex() { 34 return sex; 35 } 36 public void setSex(String sex) { 37 this.sex = sex; 38 } 39 public Teacher(String name, int age, String sex) { 40 super(); 41 this.name = name; 42 this.age = age; 43 this.sex = sex; 44 } 45 public Teacher() { 46 super(); 47 // TODO Auto-generated constructor stub 48 } 49 @Override 50 public String toString() { 51 return "Teacher [name=" + name + ", age=" + age + ", sex=" + sex + "]"; 52 } 53 54 }

1 package com.vince; 2 3 public class Student { 4 5 private String name; 6 private int age; 7 private Teacher teacher; 8 9 public String getName() { 10 return name; 11 } 12 public void setName(String name) { 13 this.name = name; 14 } 15 public int getAge() { 16 return age; 17 } 18 public void setAge(int age) { 19 this.age = age; 20 } 21 public Student(String name, int age) { 22 super(); 23 this.name = name; 24 this.age = age; 25 } 26 public Student() { 27 super(); 28 // TODO Auto-generated constructor stub 29 } 30 @Override 31 public String toString() { 32 return "Student [name=" + name + ", age=" + age + "]"; 33 } 34 public Teacher getTeacher() { 35 return teacher; 36 } 37 public void setTeacher(Teacher teacher) { 38 this.teacher = teacher; 39 } 40 41 }

1 package com.vince; 2 3 import java.util.Iterator; 4 5 6 7 public class OneToManyDemo { 8 public static void main(String[] args) { 9 10 Teacher t1 = new Teacher("张老师",18,"女"); 11 Student s1 = new Student("小李",10); 12 Student s2 = new Student("小王",12); 13 Student s3 = new Student("小赵",11); 14 15 //关联关系: 16 t1.getStudents().add(s1); 17 t1.getStudents().add(s2); 18 t1.getStudents().add(s3); 19 20 s1.setTeacher(t1); 21 s2.setTeacher(t1); 22 s3.setTeacher(t1); 23 24 Print(t1); 25 } 26 27 private static void Print(Teacher t1) { 28 // TODO Auto-generated method stub 29 System.out.println(t1.getName()); 30 for(Student s: t1.getStudents()) { 31 System.out.println(s); 32 } 33 } 34 35 }
多对多关系(不建议存在这种方式,关系复杂):
一般把多对多分成两个一对多关系:


1 package iterator; 2 3 /** 4 * 迭代器接口的具体实现类 5 * @author vince 6 * @description 7 */ 8 public class ConcreteIterator implements Iterator{ 9 10 private MyList list = null; 11 private int index;//迭代器的指针 12 public ConcreteIterator(MyList list) { 13 this.list = list; 14 } 15 @Override 16 public boolean hasNext() { 17 if(index>=list.getSize()) 18 return false; 19 else return true; 20 } 21 22 @Override 23 public Object next() { 24 Object obj = list.get(index); 25 index++; 26 return obj; 27 } 28 29 }

1 package iterator; 2 3 /** 4 * 迭代器的接口 5 * @author vince 6 * @description 7 */ 8 public interface Iterator { 9 public boolean hasNext(); 10 public Object next(); 11 }

1 package iterator; 2 3 /** 4 * 容器的接口 5 * @author vince 6 * @description 7 */ 8 public interface MyList { 9 void add(Object e); 10 Object get(int index); 11 Iterator iterator(); 12 int getSize(); 13 14 }

1 package iterator; 2 3 /** 4 * 迭代器模式 5 提供一个方法按顺序遍历一个集合内的元素,而又不需要暴露该对象的内部表示。 6 7 应用场景 8 1、访问一个聚合的对象,而不需要暴露对象的内部表示 9 2、支持对聚合对象的多种遍历 10 3、对遍历不同的对象,提供统一的接口。 11 12 迭代器模式的角色构成 13 (1)迭代器角色(Iterator):定义遍历元素所需要的方法,一般来说会有这么三个方法: 14 取得下一个元素的方法next(),判断是否遍历结束的方法hasNext()),移出当前对象的方法remove(), 15 (2)具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代。 16 (3)容器角色(Aggregate): 一般是一个接口,提供一个iterator()方法, 17 例如java中的Collection接口,List接口,Set接口等 18 (4)具体容器角色(ConcreteAggregate):就是抽象容器的具体实现类, 19 比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList, 20 Set接口的哈希列表的实现HashSet等。 21 22 * @author vince 23 * @description 24 */ 25 public class Test { 26 27 public static void main(String[] args) { 28 MyList list = new ConcreteAggregate(); 29 list.add("刘备"); 30 list.add("张飞"); 31 list.add("关羽"); 32 list.add("曹操"); 33 list.add("诸葛亮"); 34 Iterator iter = list.iterator(); 35 while(iter.hasNext()){ 36 System.out.println(iter.next()); 37 } 38 } 39 40 }
https://blog.csdn.net/feiyanaffection/article/details/81394745