黑马程序员 集合学习

来源:互联网 发布:原生js获取index 编辑:程序博客网 时间:2024/06/02 12:54

----------- android培训java培训期待与您交流! ------------

 

数组(Array)和集合(Collection)的关系:

相同:都是装数据的容器。

不同:数组里装的是固定长度的任意类型数据。集合的元素只能是对象,而不能是基本数据类型。

数组和集合互转:

数组转为集合:用Arrays.asList();将数组转成List集合。如果数组中的元素都是对象,则转为集合后,数组中的元素就直接转成集合中的元素;如果是基本数据类型的数组,则将整个数组当成对象(此时类型是数组类型)存入集合中。

集合转为数组:Collection.toArray();

 

集合总述:

/* * 为什么会出现集合? * 答:数据多了用对象封装,对象多了用集合封装。 *  * 为什么会出现那么多的集合容器? * 答:因为每个集合容器对对象的存储方式(即数据结构)不一样。 *  * 1、add(Object obj),参数类型为Object以便于接收任意类型对象 * 2、集合中存储的都是对象的引用(对象首地址) *  * 迭代器:取出元素的方式 * 就是那夹玩具用的夹子。 *  * Collection * List:元素的存取是有序的,元素可以重复:因为该体系 有索引 * ArrayList:底层使用的是数组结构,特点:查询快,增删稍慢,线程不同步 * LinkedList: 底层使用的是链表数据结构,特点:增删快,查询稍慢,线程不同步 * Vector:底层是数组结构,线程同步,被ArrayList替代了。  * 若多线程,可以自己加锁,也可以交给jvm处理(给它一个不安全,返回一个安全的) *  * Set:元素的存取是无序的(存入和取出的顺序不一定一致),元素不可以重复 * HashSet:底层使用的是哈唏表,线程不同步 * HashSet如何保证元素的唯一性? * 先判断hashCode再判断equals * 注意:对于判断元素是否存在以及删除元素等操作,先判断的是元素的hashCode再比较equals * TreeSet:可以对Set集合中的元素进行排序(一般是自然顺序或叫默认顺序) * 底层使用的是二叉树,线程不同步 * TreeSet如何保证元素唯一性? * compareTo()方法return 0; *  * TreeSet第一种排序方式:让元素自身具备比较性,定义比较方法(元素类自身实现Comparable接口,实现它的compareTo(Object obj)方法) * TreeSet第一种排序方式:让集合具备比较性,定义比较器(实现Comparator接口,覆盖compare()),再将比较器传递给TreeSet集合的构造函数 * 当两种排序都存在时,以比较器为主 *  * 排序时,当主要条件相同时,一定要判断次要条件。 */import java.util.*;public class CollectionDemo {public static void main(String[] args) {Collection c = new ArrayList();c.add("Hello");c.add("java");c.add(97);c.add(true);c.add('a');/*Iterator it = c.iterator();//获取迭代器,用于取出集合中的元素int i = 0;while(it.hasNext()) {//遍历集合System.out.println("Iterator:.." + ++i + "..." + it.next());}*///用for循环,由于it定义在局部,循环结束,会释放内存空间for(Iterator it = c.iterator(); it.hasNext();) {System.out.println(it.next());}}public static void quJiaoJi_Method() {Collection c1 = new ArrayList();c1.add("Hello");c1.add("java");c1.add(97);c1.add(true);c1.add('a');Collection c2 = new ArrayList();c2.add("Hello");c2.add("java");c2.add(65);c2.add(false);c2.add('a');//boolean b = c2.retainAll(c1);//取交集,c2中只保留和c1中相同的元素c2.removeAll(c1);  //去交集,c2中只保留和c1中不同的元素System.out.println(c2);//System.out.println(b);System.out.println(c1);}public static void base_Method() {Collection c = new ArrayList();//1、添加c.add("Hello");c.add("java");c.add(97);c.add(true);c.add('a');System.out.println("原集合:" + c);//2、查System.out.println("集合中元素个数 : " + c.size());//打印集合元素个数String s = "java";System.out.println("是否包含java :" + c.contains(s));//是否包含某个元素//3、删除//c.clear();//清空集合内的元素c.remove(true);//移除集合中的某个元素System.out.println("移除后:"+ c);}}


List集合:

import java.util.*;/* * List集合判断元素是否相同,依据的是元素的equals方法 *  * List特有方法:凡是能操作角标的方法 * 增:void add(int index, E element)  boolean addAll(int index, Collection<? extends E> c)   * 删:E remove(int index)  * 改:E set(int index, E element)  * 查:E get(int index) * ListIterator<E> listIterator(int index)    List<E> subList(int fromIndex, int toIndex)        List集合特有的迭代器。ListIterator是Iterator的子接口 * 在迭代时,不能通过集合对象的方法来操作集合中的元素,会发生ConcurrentModificationException异常  * 所以在迭代过程中,只能使用迭代器的方法操作元素,但Iterator的方法只有删、取出、判断,如果要进行其它 * 操作如添加、修改等,就需要使用其子接口ListIterator来实现。 *  * 该接口只能通过List集合的listIterator()方法获取。 *  */public class ListDemo {public static void main(String[] args) {ArrayList al = new ArrayList();al.add("Hello");al.add("java");al.add(97);al.add(true);al.add('a');System.out.println("原集合:" + al);//演示列表迭代器ListIterator li = al.listIterator();System.out.println(li.hasNext());//trueSystem.out.println(li.hasPrevious());//falsewhile(li.hasNext()) {Object obj = li.next();if(obj.equals("java")) {li.add("world");//用列表迭代器向集合中添加元素}}System.out.println(al);System.out.println(li.hasNext());//trueSystem.out.println(li.hasPrevious());//true}public static void method() {ArrayList al = new ArrayList();al.add("Hello");al.add("java");al.add(97);al.add(true);al.add('a');System.out.println("原集合:" + al);al.add(3, "你好");//在指定位置插入元素System.out.println(al);al.remove(2);//删除指定位置上的元素System.out.println(al);al.set(4, "world");//修改指定位置上的元素System.out.println(al);String s = (String)al.get(1);//获取指定位置上的元素System.out.println(s);List list = al.subList(2, 5);//获取子ListSystem.out.println("subList:" + list);//获取所有元素,方式一:for(int x=0; x<al.size(); x++) {System.out.println("size方式:........" + al.get(x));}//获取所有元素,方式二:for(Iterator it = al.iterator(); it.hasNext();) {System.out.println("iterator方式:_______________" + it.next());}}}

LindedList的特有方法:

/* * LindedList特有方法: * void addFirst(E e)   * void addLast(E e)  *  * E getFirst() //获取元素,元素不删除。若集合中没有元素会抛出异常NoSuchElementException * E getLast()  *  * E removeFirst() //获取元素,并且将元素删除。若集合中没有元素会抛出异常NoSuchElementException * E removeLast()  *  * JDK1.6出现的替代方法: * boolean offerFirst(E e)  * boolean offerLast(E e)  *  * E peekFirst() //获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。 * E peekLast()  *  * E pollFirst() //获取并移除此列表的第一个元素;如果此列表为空,则返回 null。 * E pollLast()  */import java.util.*;public class LinkedListDemo {public static void main(String[] args) {LinkedList link = new LinkedList();link.addFirst("java01");link.addFirst("java02");link.addFirst("java03");link.addFirst("java04");System.out.println(link);//[java04, java03, java02, java01]while(!link.isEmpty()) {//不用迭代获取所有元素System.out.println(link.removeFirst());}}}


Vector的枚举:

(现已很少用到)Vector已被ArrayList替代,若要同步,可在代码中添加同步,还可以用Collections的工具类完成同步功能。

/* * 枚举就是Vector特有的取出方式 *  * 枚举和迭代是一样的,而枚举的名称及方法名都过长 ,所以被迭代器取代了。 */import java.util.*;public class VectorDemo {public static void main(String[] args) {Vector v = new Vector();v.add("java1");v.add("java2");v.add("java3");v.add("java4");for(Enumeration er = v.elements(); er.hasMoreElements();) {System.out.println(er.nextElement());} }}

 

HashSet中Person对象的hashCode计算方法int hashCode() {return name.hashCode() + age*39}

TreeSet的自然排序:

import java.util.*;/* * Set集合功能和Collection一致 *  * TreeSet存储自定义对象,要求对象类要实现Comparable接口,实现它的compareTo(Object obj)方法 * */public class TreeSetDemo {public static void main(String[] args) {TreeSet<Student> ts = new TreeSet<Student>();ts.add(new Student("张三", 23));ts.add(new Student("李四", 20));ts.add(new Student("李二", 20));ts.add(new Student("王五", 25));for(Iterator it = ts.iterator(); it.hasNext();) {System.out.println(it.next());}}}class Student implements Comparable<Student>{private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}public int compareTo(Student s) {//if(!(obj instanceof Student))//throw new RuntimeException("不是学生");//Student s = (Student)obj;if(this.age == s.age)return this.name.compareTo(s.name);return this.age-s.age;}public String toString() {return this.name + "...." + this.age;}}


 

元素用二叉树怎么存入的怎么取出?(即存入顺序和取出顺序一致) 

答:元素类实现Comparable接口的compareTo()时直接返回1。(存入时全往右边放,取出时即为存入的顺序,从小往大取,被称为自然顺序)

 

泛型:详见http://blog.csdn.net/wyl530274554/article/details/7764757

 

Map集合的键值对:

/* * Map集合:存储键值对。一对一对往里存。并且要保证唯一性。 *  * 何时使用Map集合? 当数据之间存在映射关系时。 *  * 1,添加 * void putAll(Map<? extends K,? extends V> m)  * V put(K key, V value)  //第二个相同存入会覆盖第一个,并返回第一个的“值” * 2,删除 * V remove(Object key)  * void clear() * 3,判断 * boolean isEmpty()  * boolean containsKey(Object key)  * boolean containsValue(Object value)  * 4,获取 * V get(Object key)  * int size()  * Collection<V> values() //获取集合中的所有的“值”,并以Collection<>返回 *  * Set<K> keySet()//可将所有键存入Set中,迭代出后,用get()方法得到所有的值。  * Set<Map.Entry<K,V>> entrySet()  *  * Map  * Hashtable:底层是哈唏表,不能存入null键和null值。线程同步。效率低 * HashMap:底层是哈唏表,允许使用null键和null值。线程不同步。效率高 * TreeMap:底层是二叉树,线程不同步,可以对Map集合的键排序。 *  * 和Set很像,其实Set集合的底层用的就是Map中的方法 *  * Map中用作键的对象必须实现hashCode和equals方法。 *  * Map集合中元素取出原理:将Map集合转成Set集合,再用迭代器取出。  * */import java.util.*;public class MapDemo {public static void main(String[] args) {Map<String, Integer> mp = new HashMap<String, Integer>();mp.put("zhangsan", 20);mp.put("lisi", 25);mp.put("wangwu", 23);mp.put("qingliu", 20);/*System.out.println(mp);System.out.println(mp.remove("lisi"));System.out.println(mp);*///1、用keySet()方式取出 :将键集存入Set集合中Set<String> keySet = mp.keySet();for(Iterator<String> it = keySet.iterator(); it.hasNext();) {String key = it.next();int value = mp.get(key);System.out.println(key+"...keySet...."+value);}//2、用entrySet(()方式取出 :将映射关系存入Set集合中,这个关系的类型就是:Map.EntrySet<Map.Entry<String, Integer>> entrySet = mp.entrySet();for(Iterator<Map.Entry<String, Integer>> it = entrySet.iterator(); it.hasNext();) {Map.Entry<String, Integer> me = it.next();String key = me.getKey();int value = me.getValue();System.out.println(key + "_______________entrySet______________" + value);}}}

 

Map集合按值排序示例:


思路:

1、将Map中的映射关系存入Set,即mp.entry();

2、将得到的Set集合转成List 

3、用Collections工具对List按指定比较进行排序

/*统计字符串”abadcdffbaeba”中每个字符出现了多少次,按次数排序并输出。例如:c : 1,e : 1,d : 2,f : 2,b : 3,a : 4*/import java.util.*;public class CharCount{public static void main(String[] args) {String str = "abadcdffbaeba";System.out.println("按指定格式输出:" + charcount(str));//c:1,e:1,d:2,f:2,b:3,a:4}public static String charcount(String str) {char[] chs = str.toCharArray();//String ---> char[]TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();//从char[]中找键,从Map集合中找值;字符作为键,出现的次数作为值存入Map集合中for(char ch : chs) {Integer value = tm.get(ch);if(value == null) {tm.put(ch, 1);}else {tm.put(ch, ++value);}}System.out.println("自然排序:"+tm);//{a=4, b=3, c=1, d=2, e=1, f=2}//按值排序:1、将映射关系对象存入Set集合中,并用Set构成List集合。2、用工具Collections对List按比较器进行排序List<Map.Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character, Integer>>(tm.entrySet());Collections.sort(list, new CharCountComparator());System.out.println("按值排序:"+list);//[c=1, e=1, d=2, f=2, b=3, a=4]//按指定格式输出:c : 1,e : 1,d : 2,f : 2,b : 3,a : 4//用迭代器取出list中映射关系,并将键值按指定格式存入StringBuilder中StringBuilder sb = new StringBuilder();for(Iterator<Map.Entry<Character, Integer>> it = list.iterator();it.hasNext();) {Map.Entry<Character, Integer> me = it.next();char key = me.getKey();int value = me.getValue();if(!it.hasNext())sb.append(key + ":" + value);else sb.append(key + ":" + value + ",");}return sb.toString();}}//比较器class CharCountComparator implements Comparator<Map.Entry<Character, Integer>>{//将映射关系先按value比较,若value相同,再按key比较public int compare(Map.Entry<Character, Integer> me1, Map.Entry<Character, Integer> me2) {if(me1.getValue() == me2.getValue())return me1.getKey().compareTo(me2.getKey());return me1.getValue() - me2.getValue();}}


 

 

集合的工具类Collections:

import java.util.*;public class CollectionsDemo {public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("abcdf");list.add("ebf");list.add("tree");list.add("ebf");list.add("bcdf");list.add("af");System.out.println("原List集合:" + list);Collections.sort(list);//对list集合排序,按自然顺序;还可以传比较器。System.out.println("自然排序后:" + list);/*Collections.fill(list, "Hello");//用指定元素替换所有元素System.out.println(list);*/int i = Collections.binarySearch(list, "af");System.out.println("“af”在哪? " + i);String s = Collections.max(list);System.out.println("最大的元素是:" + s);Collections.replaceAll(list, "ebf", "Hello");System.out.println("替换后:" + list);Collections.reverse(list);System.out.println("反转后:" + list);Collections.swap(list, 2, 5);System.out.println("交换后:" + list);//static <T> Comparator<T>  reverseOrder(Comparator<T> cmp)  //★★强行逆转比较器//static <T> Collection<T>  synchronizedCollection(Collection<T> c)  //★★非同步变成同步Collections.shuffle(list);//将List集合中的元素随机排序。比如:洗牌System.out.println(list);}}

 




Properties集合:

是Hashtable的子类,具备Map集合的特点。它里面的键值对都是字符串。

Properties 可保存在流中或从流中加载。是集合和IO流技术相结合的集合容器。

可以用于键值对形式的配置文件。

此类是线程安全的。

 该集合的常用方法:

import java.util.*;import java.io.*;public class PropertiesDemo {public static void main(String[] args) throws Exception {Properties prop = new Properties();//添加元素prop.setProperty("李四", "20");System.out.println(prop.setProperty("张三", "21"));//打印设置时返回的值(属性列表中指定键的旧值,如果没有值,则为 null。)System.out.println(prop.setProperty("李四", "23"));//打印设置后的集合System.out.println(prop);//获取元素,以键找值System.out.println(prop.getProperty("张三"));//集合中的键集Set<String> set = prop.stringPropertyNames();System.out.println(set);//[张三, 李四]//读取配置文件(用相对路径时,放本项目下),将硬盘上的文件加载到了内存中FileReader fr = new FileReader("Properties.config");Properties prop2 = new Properties();prop2.load(fr);//System.out.println(prop2);prop2.list(System.out);//向内存中的集合中添加元素后存入相应的文件中prop2.setProperty("wyl", "35");BufferedWriter fw = new BufferedWriter(new FileWriter("Properties.config"));prop2.store(fw, "This is newer");prop2.list(System.out);}}


演示软件试用次数限制:

建立配置文件,记录使用的次数

import java.util.*;import java.io.*;public class RunCount {public static void main(String[] args) throws Exception {//创建流对象关联配置文件File file = new File("count.properties");if(!file.exists())file.createNewFile();FileInputStream fis = new FileInputStream(file);//创建Properties对象,用于操作配置文件Properties prop = new Properties();//将流中数据加载到集合当中prop.load(fis);String value = prop.getProperty("time");//获取使用次数int count = 0;if(value != null) {count = Integer.parseInt(value);//String-->int//如果软件使用次数达到5次,则提示用户试用期快到if(count>=5) {System.out.println("使用次数已到!");return;}}count++;//使用一次count自增prop.setProperty("time", count+"");//信息存入集合中FileOutputStream fos = new FileOutputStream(file);prop.store(fos, "");//集合中的数据存入硬盘的文件中fos.close();fis.close();}}


  

 ----------------------- android培训java培训、期待与您交流! ----------------------

 详情请查看:http://edu.csdn.net/heima