分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
集合提供给我们的是许多实用的数据结构。
如果熟悉C++的STL,就会更容易接触java的集合类,C++的STL的缺点是复杂而且比较低效。
对象的引用强度分为四个级别:在java.lang.ref中
1.强引用:当内存不足时,这些对象也绝对不会被回收。
2.软引用:当内存不足时,会回收对象内存,用来实现内存敏感的告诉缓存。
3.弱引用:无论内存是否紧张,只要被垃圾回收器发现,则立即回收。
4.虚引用:与没有引用一样。
错误种类:
1.编译器错误:在javac阶段出现的错误,必须解决。
2.运行时错误:在java时抛出运行时异常。
jdk升级目标:将运行时异常转变成编译时错误。
如果要实现一个集合,则可以预先设定一个接口,规定方法的名称,这样可以使得给予用户所见的只有方法的名称,而实现的方法可以自己变动。
迭代器:用于遍历一个容器的接口。
Iterator主要用于集合的输出,因此只要看到输出,就最好使用iterator接口。
Iterator在遍历集合时,不能用另一个线程去修改集合,不然会抛出java.util.ConcurrentModificationException,因为Iterator运用了快速失败机制,因此一旦检测到集合被修改,立即抛出异常。
Iterator和Enumeration接口的比较
一般Enumeration通常用在vector输出,因为Vector中有element()方法返回Enumeration接口。
共同点是都能够遍历一个容器的每个元素。
遍历方式1:
遍历方式2:for each:
for each遍历形式的适用条件:实现Iterable接口。
移除元素:在调用remove之前,必须要调用next。
Collection
代码示例:将链表集合变成数组。
package org.LinkedList;import java.util.LinkedList;public class toArrayTest { public static void main(String[] args) { LinkedList list1 = new LinkedList(); list1.add("a"); list1.add("b"); list1.add("c"); list1.add("d"); String[]arr = list1.toArray(new String[0]); for(String e:arr) System.out.println(e); }}
特别要注意:remove方法移除依赖于迭代器的状态。所以一般很少使用!因为List接口存在remove(Object obj)方法。
在iterator迭代中使用List的remove方法会出现一个问题:一旦执行了remove方法,就直接跳出循环。
因此在iterator迭代输出时,不能使用List的remove方法。
代码实例:
package org.Collections;import java.util.*;public class removeExceptionTest { public static void main(String[] args) { List list = new LinkedList(); list.add("a"); list.add("b"); list.add("c"); Iterator iterator = list.iterator(); while (iterator.hasNext()) { String str = iterator.next(); if ("b".equals(str)) { list.remove(str); // 在移除b后就跳出循环 } else { System.out.println(str);// 只输出了a } } }}
AbstractCollection
由于ArrayList是由数组实现的,因此添加和删除的效率很低。因此引入了链表
当数据量大,并且有很多的插入删除操作,则使用链表。
专有迭代器:ListIterator
迭代器默认是在最前面的。
因此当创建了一个ListIterator后,直接进行由后向前遍历,是不行的!!
示例:
package org.Collections;import java.util.LinkedList;import java.util.ListIterator;public class ListIteratorTest { public static void main(String[] args) { LinkedList list1 = new LinkedList(); list1.add(1); list1.add(2); list1.add(3); ListIterator iterator = list1.listIterator(); System.out.println("输出链表:"); while(iterator.hasPrevious()) // 不能输出,因为默认迭代器在最前 { System.out.println(iterator.previous()); } }}
举例:
(1)双端队列Deque:
(2)堆栈Stack:
(3)队列
共同点:有着几乎共同的方法。
相异点:vector
特点:
常用函数:
术语:
注意:在元素加入HashSet后最好不要改变其哈希值!
代码示例:
package org.HashSet;import java.util.*;public class HashSetTest { public static void main(String[] args) { HashSet set1 = new HashSet(); Person p1 = new Person("张三",15); Person p2 = new Person("李四",16); Person p3 = new Person("王五",17); Person p4 = new Person("赵六",18); Person p5 = new Person("张三",15); set1.add(p1); set1.add(p2); set1.add(p3); set1.add(p4); System.out.println(set1); set1.add(p5); //添加重复元素 System.out.println(set1);//集合不变 p1.setAge(100); //修改hash值 System.out.println(set1);//集合元素被修改 set1.remove(p1); //试图删除p1,但是没有成功 System.out.println(set1);//集合元素不变,没有删除 }}class Person { String name; int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; 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; Person other = (Person) obj; if (age != other.age) 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 "Person [name=" + name + ", age=" + age + "]"; } }
特点:
插入的元素必须都是可比较的。实现方式有两种:
(1)插入元素的类实现Comparable接口.因此这个实现必须在开发阶段实现。但是如果有的类开发时没有实现这个接口呢?则引入第二种方法。
(2)继承Comparator
常用函数:
package org.TreeSet;import java.util.*;public class TreeSetTest { public static void main(String[] args) { TreeSet set1 = new TreeSet(new Comparator() { public int compare(Student a , Student b) { if(a.getScore() < b.getScore()) return -1; else if(a.getScore() > b.getScore()) return 1; else return 0; } }); Student stu1 = new Student("张三",90); Student stu2 = new Student("李四",80); Student stu3 = new Student("王五",100); Student stu4 = new Student("赵六",90); set1.add(stu1); set1.add(stu2); set1.add(stu3); System.out.println(set1); set1.add(stu4); //插入score相同的值时将不成功 System.out.println(set1);//赵六没有插入成功 }}class Student { //预先并没有给定比较器 String name; double score; public Student(String name, double score) { super(); this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } @Override public String toString() { return "Student [name=" + name + ", score=" + score + "]"; }}
当对于排序不要求时则用HashSet,对排序有要求则用TreeSet。
特点:
函数:
Map.Entry
(1)getKey();
(2)getValue();
示例代码:
package org.Collections;import java.util.*;public class HashMapTest { public static void main(String[] args) { HashMap students = new HashMap(); students.put(1, "张三"); students.put(2, "李四"); students.put(3, "王五"); students.put(4, "赵六"); Set ids = students.keySet(); Collection names = students.values(); System.out.println(ids); students.remove(1); //在原来映射表中删除一个元素 System.out.println(ids);//在视图中反应出来 ids.remove(4); //在视图中删除,则在原来映射表中也会同样删除,因此视图和原来映射表是同步的 //但是视图不能添加元素 printMaps(students); names.remove("王五"); printMaps(students); } public static void printMaps(HashMapmap) { Set> maps = map.entrySet(); for(Map.Entry entry:maps) { System.out.println(entry.getKey()+" "+entry.getValue()); } System.out.println("************************"); }}
对键进行排序,其他特点类似TreeSet
添加比较器:
TreeMap
public int compare(String o1,String o2){
return o2.compareTo(o1);
}
});
可以实现反序;
常用方法:
(1)containsKey(Object o);
(2)containsValue(Object o);
功能和HashMap一样,区别在于Hashtable是线程同步的。
特点:
常用函数:
WeakHashMap会自动移除没有使用的键值对,由垃圾回收器回收。
package org.Collections;import java.util.Map;import java.util.*;public class WeakHashMapTest { public static void main(String[] args) { Map map = new WeakHashMap(); map.put(new String("A"),new String("a"));//创建三个临时的类型 map.put(new String("B"),new String("b")); map.put(new String("C"),new String("c")); System.out.println("垃圾收集之前:"); System.out.println(map); System.gc();//强制进行垃圾收集 System.out.println("垃圾收集之后:"); System.out.println(map);//元素被垃圾收集,因此为空 }}
LinkedHashSet
package org.Collections;import java.util.*;import java.util.Map;import java.util.Set;public class LinkedHashMapTest { public static void main(String[] args) { LinkedHashMap students = new LinkedHashMap(); //插入顺序 students.put(1, "张三"); students.put(2, "李四"); students.put(3, "王五"); students.put(4, "赵六"); students.get(1); printMaps(students); LinkedHashMap students2 = new LinkedHashMap(16,0.75f,true); //访问顺序,按照列表进行访问,当对一个元素调用get或put方法时,则将这个元素放置列表末尾 students2.put(1, "张三");//将1, 张三 放到列表末尾 students2.put(2, "李四");//同上 students2.put(3, "王五");//同上 students2.put(4, "赵六");//同上 students2.get(1); //同上 printMaps(students2);//结果李四在第一个 } public static void printMaps(HashMap map) { Set> maps = map.entrySet(); for (Map.Entry entry : maps) { System.out.println(entry.getKey() + " " + entry.getValue()); } System.out.println("************************"); }}
package org.Collections;import java.util.HashMap;import java.util.*;public class IdentityHashMapTest { public static void main(String[] args) { Map map = new IdentityHashMap(); map.put(new Person("张三",15), "张三"); map.put(new Person("李四",30), "李四"); map.put(new Person("张三",15), "zhangsan"); //只要key的地址不一样,则可以允许键值重复 Set> entry = map.entrySet(); for(Map.Entrye :entry){ System.out.println(e.getKey()+"--->"+e.getValue()); } }}
特点:没有构造方法。用静态工厂方法,类似线程池。
工厂方法:
(1)EnumSet
(2)EnumSet
(3)EnumSet
构造:EnumMap(Class
RandomAccess接口是标记接口,实现了这个接口的类适用于随机访问方法。
视图能够把原来的集合的一部分给用户看,但是又不是单纯的把那部分值复制,而是当改变视图的值会对原来的集合进行修改。
视图会随着原始集合的更改而更新。
(1)List
比如:
String[] str=new String[5];
List
(2)对于List类:
List
(3)对于SortedSet
(4)对于SortedMap
有了前面的视图操作,我们就可以进行批操作,即对于大量数据进行移动。
可以利用视图和批操作结合。
Collections集合工具类:
Collections和Collection没有关系。
经过同步视图后视图的所有方法都是同步的。
int Collections.binarySearch(List
int Collections.binarySearch(List
二分查找的集合必须是实现RandomAccess的。
package org.Collections;import java.util.*;public class BinarySearchTest { public static void main(String[] args) { List list = new ArrayList(); list.add("c"); list.add("b"); list.add("a"); list.add("e"); Collections.sort(list); int i = Collections.binarySearch(list, "c"); System.out.println("c的位置是:" + i); int j = Collections.binarySearch(list, "d");// 没有找到d System.out.println("d的位置是:" + j); list.add((-j - 1), "d");// -j-1就是能够维持有序的插入位置 System.out.println(list); }}
Collections.copy(List
Collections.fill(List
int f=Collections.frequency(Collection
boolean b=Collections.disjoint(Collection a,Collection b);
内容反转
Collections.reverse(Collection<> col);
例如:
String[] str;
List
可以把list赋给任何一个集合。
注意:asList返回的是数组的视图,因此如果视图修改了,则数组也会被同步修改!
import java.util.*;public class AsListDemo{ public static void main(String args[]){ String[]arr = {"4","3","2","5","6","7","1"}; List list = Arrays.asList(arr); Collections.sort(list); System.out.println("*****排序*******"); for(String a:arr) System.out.println(a); }}
例如:
如果要把list换成数组,则可以
String [] str=list.toArray(new String[list.size]);
集合是可扩展的,因为设计者预先给我们一个abstract的抽象类,便于我们扩展,实现自己的功能。
package org.Collections;import java.util.*;public class CircularQueueTest { public static void main(String[] args) { CircularArrayQueue queue = new CircularArrayQueue(3); queue.add(1); queue.add(2); queue.add(3); boolean ok = queue.offer(4); System.out.println(ok); System.out.println(queue); Iterator iterator = queue.iterator(); while(iterator.hasNext()) System.out.println(iterator.next()); }}class CircularArrayQueue<T> extends AbstractQueue<T> { private T[] elem; private int count; private int head; private int tail; public CircularArrayQueue(int capacity) { super(); elem = (T[])new Object[capacity]; count = 0; head = 0; tail = 0; } @Override public boolean offer(T e) { if (count == elem.length) return false; else { elem[tail] = e; tail=(tail+1 == elem.length)?0:(tail+1); count++; return true; } } @Override public T poll() { if (size() == 0) return null; T r = elem[head]; head = (head + 1 == elem.length) ? 0 : (head + 1); count--; return r; } @Override public T peek() { if (size() == 0) return null; return elem[head]; } @Override public Iterator iterator() { return new QueueIterator(); } @Override public int size() { return count; } class QueueIterator implements Iterator<T> { int current; boolean hasnext; public QueueIterator() { super(); current = 0; hasnext =false; } @Override public boolean hasNext() { return current < count; } @Override public T next() { if(current+1 <= count){ hasnext = true; return elem[current++]; } else return null; } @Override public void remove() { } }}
记住:在平常使用这些集合类是不要对具体的类太苛刻,这样就不灵活。比如在函数参数上、函数返回值等。
比如f(ArrayList
一般我们都调用getProperty(String key);和setProperty(String key, String value);获得和设置属性。
特点是:
package org.Collections;import java.io.*;import java.util.*;public class PropertiesTest { public static void main(String[] args)throws Exception { FileInputStream in = new FileInputStream("config.properties"); Properties p = new Properties(); p.load(in); in.close(); String str1 = p.getProperty("name");//获得name属性的值 p.setProperty("gender","male");//把这个键值对放入属性集 FileOutputStream out = new FileOutputStream("config.properties"); p.store(out, "\0");//把现在的属性集存入文件 out.close(); }}
String[][][]str1 = new String[1][][2]; //错误,因为要从低维到高维,创建每一维数组
(2)String类有toCharArray();返回字符数组。
EnumMap也是Map的子类,规定key必须是enum类型;
注意:在EnumMap<>构造函数中必须要传入参数Enum类型的class;比如:
enum Grade{};
EnumMap
import java.util.EnumMap;public class EnumDemo { enum Grade {A,B,C,D}; public static void main(String args[]){ EnumMap maps = new EnumMap(EnumDemo.Grade.class); maps.put(Grade.A, "A"); maps.put(Grade.B, "B"); maps.put(Grade.C, "C"); maps.put(Grade.D, "D"); System.out.println(maps.get(Grade.A)); }}
for-each循环的集合必须实现java.lang.Iterable,从而能够支持迭代。
package org.impl;import java.util.EnumSet;import java.util.Set;public class Log4jDemo { enum Grade {A,B,C}; public static void main(String args[]){ Set set = EnumSet.allOf(Grade.class); //print A,B,C for(Grade g:set){ System.out.println(g); } SetnoneSet = EnumSet.noneOf(Grade.class); noneSet.add(Grade.A); Set rangeSet = EnumSet.range(Grade.A, Grade.B); //print A,B for(Grade g:rangeSet){ System.out.println(g); } }}
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow