java:集合

 

 

 

 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 }
View Code

 

  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 }
Hashset判断重复值

 

  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 }
View Code

 

 


  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 }
View Code


 


 

 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 }
Teacher.java
 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 }
Student.java
 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 }
OneToManyDemo.java

多对多关系(不建议存在这种方式,关系复杂):

   一般把多对多分成两个一对多关系:

 


ConcreteAggregate
 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 }
ConcreteIterator
 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 }
Iterator
 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 }
MyList
 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 }
Test

 

https://blog.csdn.net/feiyanaffection/article/details/81394745

原文地址:https://www.cnblogs.com/juham/p/15668431.html