java集合框架22

思想:在面向对象的思想里,一种数据结构被认为是一种容器。在本质上来讲是一个类,提供方法支持查找,插入和删除等等操作。

Java集合框架支持以下俩种类型的容器:

存储一个元素集合,简称为集合Collection

存储键值对,称为图Map

集合collection

三种主要类型 : 规则集(set) , 线型表(List) , 队列(Queue)

set: 存储一组不重复的数据

List: 存储由元素构成的有序集合

Queue: 存储先进先出方式处理的对象

细说Collection接口: 它是处理对象集合的根接口。有基本的添加和删除操作。有类似于规则集的并,差,交运算。

简单的

   

细致的

规则集Set接口

Set接口的三个孩子是 散列类HashSet,链式散列集LinkedHashSet和树形集TreeSet

散列集HashSet

在这之前散列是啥意思?  ::: -》  Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射,
pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。 简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
 ------来源百度百科

这个看起来和MD5加密算法一样,对吧。 继续走

HashSet的无参构造函数有点意思  :  可以创建空的,也可以由一个现有的集合来创建

默认情况下初始容量为16而客座率为0.75,如果知道集合的大小可自己指定其参数从而不需要系统自动分配。

那问题来了,客座率是啥?

我的理解是: 集合大致会使用其申请空间的百分比,比如你new一个列数为10的一维数组,并没有放满10个,而是7个,这样客座率为0.7

正式解答

客座率是测量在增加规则集的容量之前,该规则集的饱满程度。在0.0~1.0之间。 当元素个数超过了容量与客座率的乘积,容量就会翻倍。 (不得不佩服java设计大师)

当然这样也有弊端,客座率高会降低空间开销,但是会增加查找时间。通常是0.75,权衡的很好 。

HashSet是用来存储互不相同的任何元素
添加到散列集中的对象必须以一种正确分散散列码的方式来实现hashCode方法。  这个是为了效率.( 其实 我也不懂这个所追求的是哪方面的效率,应该是查找吧,求大神解答)

它的api中有三个方法很好玩,一个addAll    removeAll   retainAll   类似于规则集中的并  差  交  运算  (难怪我在看数据挖掘时代码中使用了Set集合,难怪如此.....)

set1.addAll(set2);       //set2是一个规则集,这样会添加set2中的元素进入set1   当然set1不会重复的

set1.removeAll(set2); //从set1中删除在set1中出现set2中的元素

set1.retainAll(set2);   //得到公共元素

链式散列集LinkedHashSet

这个支持对规则集的元素排序,只是对插入的时间来排序。

其余和上面的一样 ,但是如果不需要排序的话就使用HashSet,因为高效率。

树形集TreeSet

这个可以确保规则集是有序的 方法headSet(toElement)
和tailSet(fromElement) 以返回规则集中元素小于toElement和大于或等于fromElement的那一部分

那么是怎么比的呢???   TreeSet实现了SortedSet接口的一个具体类,有comparableTo方法(因为添加到规则集中的对象都是Comparable的实例) 许多Java API中的类,例如String,Date,Calender类以及所有基本数据类型的包装类,都实现了Comparable接口,这种方法定义的顺序通常称为自然顺序。

Set<String> set=new TreeSet<String>();
  set.add("London");
  set.add("Paris");
  set.add("New York");
  set.add("San Francisco");
  set.add("Beijing");
  set.add("New York");

  TreeSet<String> treeSet=new TreeSet<String>(set);

  System.out.println(treeSet);
  System.out.println("first():"+treeSet.first());
  System.out.println("last():"+treeSet.last());
  System.out.println("headSet():"+treeSet.headSet("New York"));  //返回之前的
  System.out.println("tailSet():"+treeSet.tailSet("New York"));  //返回之后的,包括它自身
  System.out.println("lower(\"p\"):"+treeSet.lower("P"));     //返回小于P的最大元素
  System.out.println("higher:"+treeSet.higher("P"));          //返回大于P的最小元素
  System.out.println("floor:"+treeSet.floor("P"));            //返回小于或等于P的最大元素
  System.out.println("ceiling:"+treeSet.ceiling("P"));        //返回大于或者等于P的最小元素
  System.out.println("poolFirst:"+treeSet.pollFirst());      //删除第一个并返回
  System.out.println("pollLast:"+treeSet.pollLast());	   //删除最后一个并返回
  System.out.println("new Set"+treeSet);

Java集合框架张的所有具体类都至少有俩个构造方法,一个是创建空集合的无参构造方法,另一个是用某个集合来创建实例的构造方法,这样,TreeSet类中就含有从集合c创建 TreeSet对象的构造方法TreeSet(Collection c)  在上面的例子里,new TreeSet(set)方法从集合set创建了一个TreeSet的一个实例,因为涉及到更新规则集,有时候会牵涉到集合的重新排序。如果不需要保持元素的排序关系,就使用散列集HashSet,因为插入和删除元素效率高,当需要一个排好序的集合时就可以从这个散列集创建一个树形集。

比较器Comparator

这个接口有俩个方法equals和compare    可以自己实现这个接口,还有Serizlizable接口(可序列化数据结构)

Compareable用于比较实现Compareable的类的对象,而Compareator用于比较没有实现Compareator的类的对象

线性表List

数组线性表  ArrayList   链表 LinkedList

增加了面向位置的操作

ArrayList用数组存储元素,这个数组是动态创建的,如果元素个数超过了数组容量,就创建一个更大的新数组,并当前数组中的所有元素都复制到新数组中。 它不能自动减少。

LinkedList在一个链表中存储元素。

如果需要通过下标随机访问元素,但是除了在末尾处之外,不能在其他位置插入或删除元素,ArrayList高效率。

如果需要在任意位置插入或删除元素,就应该选择LinkedList。

List<Integer> alist=new ArrayList<Integer>();
   alist.add(1);   //10
   alist.add(2);
   alist.add(3);
   alist.add(1);   //30
   alist.add(4);    //4  1  30  3  2  1  10
   alist.add(0,10);  //把下标为0的元素挤到下标为1的地方
   alist.add(3,30);
   System.out.println(" A list of integer in array list:\n"+alist);

   LinkedList<Object> llist=new LinkedList<Object>(alist);
   llist.add(1,"red");
   llist.removeLast();
   llist.addFirst("green");

   //顺序输出
   System.out.println("Display the linked list forward:");
   ListIterator<Object> iterator=llist.listIterator();
   while(iterator.hasNext()){
    System.out.print(iterator.next()+"  ");
   }
   System.out.println();

   //逆序输出
   System.out.println("Display the linked list backward");
   iterator=llist.listIterator(llist.size());
   while(iterator.hasPrevious()){
    System.out.print(iterator.previous()+"  ");
   }

总结: 若要提取元素或在线型表的尾部插入和删除元素,ArrayList效率高,如果是任意位置,那么LinkedList效率高。

Java提供了静态的asList方法创建线性表

线性表和集合的静态方法

sort(List)                                        排序

binarySearch(List,Comparator)       二分法查找

reverse(List)                                   颠倒指定的列表

reverseOrder()                                返回逆序的比较器

shuffle(List)                                    随机打乱指定的列表

shuffle(List,Random)

copy(List,List)                                 将源列表复制给目标列表

nCopies(int,Object)                        返回含n个副本的列表

fill(List,Object)                                用对象填充列表

max(Collection,Comparator)          返回max对象

min(Collection,Comparator)

dijoint(Collection,Collection)        没有公共元素就返回true

frequency(Collection,Object)        返回指定元素的出现次数

List<String> list=Arrays.asList("red","green","blue");
  Collections.sort(list);           //排序
  System.out.println(list);
  Collections.sort(list,Collections.reverseOrder());    //逆序输出
  System.out.println(list);
  List<Integer> list1=Arrays.asList(2,4,7,10,11,45,50,59,60,69);
  System.out.println("(1) Index:"+Collections.binarySearch(list1,7));
  System.out.println("(2) Index:"+Collections.binarySearch(list1,9));
  System.out.println("(3) Index:"+Collections.binarySearch(list,"blue"));     //-1
  System.out.println("(4) Index:"+Collections.binarySearch(list,"cyna"));
  Collections.reverse(list);           //逆序排序
  System.out.println("reverse:::::"+list);
  Collections.reverse(list);
  System.out.println("reverse2:::::"+list);
  Collections.shuffle(list,new Random(2));   //随机打乱顺序
  System.out.println("shuffle::::"+list);
  System.out.println("*********************copy()**********************");

  List<String> list2=Arrays.asList("yellow","red","green","blue");
  List<String> list3=Arrays.asList("white","black");
  Collections.copy(list2,list3);
  System.out.println(list2);
  List<Integer> list4=Collections.nCopies(5,5);
   /*用nCopies()方法创建的线性表是不可变的,不能在该线性表中添加删除或更新*/
  //list4.add(new Integer(6));
  System.out.println(list4);
  List<String> list5=Arrays.asList("red","green","blue");
  Collections.fill(list5,"aha~");       //全部替换成"aha~"
  System.out.println("fille():"+list5);

性能测试

public static void main(String[] args) {

       Collection<Integer> set1=new HashSet<Integer>();
       System.out.println("the time of HashSet  is:"+getTestTime(set1,500000)+"milliseconds");

       Collection<Integer> set2=new LinkedHashSet<Integer>();
       System.out.println("the time of LinkedHashSet is:"+getTestTime(set2,500000)+"milliseconds");
       Collection<Integer> set3=new TreeSet<Integer>();
       System.out.println("the time of TreeSet is:"+getTestTime(set3,500000)+"milliseconds");

     Collection<Integer> set4=new ArrayList<Integer>();
     System.out.println("the time of ArrayList  is:"+getTestTime(set4,500000)+"milliseconds");
     Collection<Integer> set5=new LinkedList<Integer>();
     System.out.println("the time of LinkedList is:"+getTestTime(set5,500000)+"milliseconds");

}
 public static long getTestTime(Collection<Integer> c , int size){
       long start=System.currentTimeMillis();
       List<Integer> list=new ArrayList<Integer>();
       for(int i=0;i<size;i++)  list.add(i);
       Collections.shuffle(list);
       for(int element: list)  c.add(element);
       Collections.shuffle(list);
       for(int element: list)   c.remove(element);
       long end=System.currentTimeMillis();
       return end-start;
 }

C:\Users\Administrator\Desktop>javac TestTreeSet.java

C:\Users\Administrator\Desktop>java TestTreeSet

the time of HashSet  is:407milliseconds

the time of LinkedHashSet is:1185milliseconds

the time of TreeSet is:1178milliseconds

the time of ArrayList  is:267940milliseconds

the time of LinkedList is:705575milliseconds

向量类Vector和栈类Stack

除了包含用于访问和修改向量的同步方法之外,和ArrayList是一样的,同步是为了防止多个线程同时访问某个向量时引起数据损坏。如果不需要这个,ArrayList效率高一些。

实现了List接口,详情查看API手册,除l了添加元素方法是同步的之外

队列和优先队列

先进先出

接口Queue<E>  一般使用LinkedList<E>来实现它

 boolean offer(E e)

将指定的元素插入此队列(如果立即可行且不会违反容量限制),当使用有容量限制的队列时,此方法通常要优于 add(E),后者可能无法插入元素,而只是抛出一个异常。

 E poll()

获取并移除此队列的头,如果此队列为空,则返回 null

 E remove()

获取并移除此队列的头。

 E peek()

获取但不移除此队列的头;如果此队列为空,则返回 null

 E element()

获取,但是不移除此队列的头。

public static void main(String[] args) {
   Queue<String> queue=new LinkedList<String>();
   queue.offer("first");
   queue.offer("second");
   queue.offer("third");
   queue.offer("fourth");
   /**
    * poll():获取并删除队列头,队列为空返回null
    * remove():获取并删除队列头,队列为空返回异常
    * peek():获取但不删除队列头,队列为空返回null
    * element():获取但不删除队列头,队列为空返回异常
    */
   System.out.println("队头为:"+queue.element());
   System.out.println("队长为:"+queue.size());
 }

类PriorityQueue<E>

构造方法摘要
PriorityQueue()

使用默认的初始容量(11)创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。

PriorityQueue(Collection<?
extends E> c)

创建包含指定 collection 中元素的 PriorityQueue

PriorityQueue(int initialCapacity)

使用指定的初始容量创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。

PriorityQueue(int initialCapacity, Comparator<?
super E> comparator)

使用指定的初始容量创建一个 PriorityQueue,并根据指定的比较器对元素进行排序。

PriorityQueue(PriorityQueue<?
extends E> c)

创建包含指定优先级队列元素的 PriorityQueue

PriorityQueue(SortedSet<?
extends E> c)

创建包含指定有序 set 元素的 PriorityQueue

public static void main(String[] args) {
     // 默认为自然排序
  PriorityQueue<String> queue=new PriorityQueue<String>();
  queue.offer("java");
  queue.offer("net");
  queue.offer("C");
  queue.offer("python");
  while(queue.size()>0){
   System.out.print(queue.remove()+"\t");
  }

  System.out.println();

  // 修改排序方式
  PriorityQueue<String> queue2=new PriorityQueue<String>(4,Collections.reverseOrder());
  queue2.offer("java");
  queue2.offer("net");
  queue2.offer("C");
  queue2.offer("python");
  while(queue2.size()>0){
   System.out.print(queue2.remove()+"\t");
  }
 }

这是一种存储键值对的容器,不能有重复的键值。

分为三种,HashMap,LinkedHashMap,TreeMap

public static void main(String[] args) {
  Map<String,Integer> hashmap=new HashMap<String, Integer>();
  hashmap.put("chenjian", 21);
  hashmap.put("liuzhenguang", 22);
  hashmap.put("guoliangjun", 23);
  hashmap.put("qiufubi", 22);
  System.out.println(hashmap);  //随机输出

  //从一个散列图创建一个树形图
  Map<String,Integer> treemap=new TreeMap<String, Integer>(hashmap);
  System.out.println(treemap);  //按照键值排序输出

  Map<String,Integer> linkedmap=new LinkedHashMap<String, Integer>(11,0.75f,false);
  linkedmap.put("chenjian", 21);
  linkedmap.put("liuzhenguang", 22);
  linkedmap.put("guoliangjun", 23);
  linkedmap.put("qiufubi", 22);
  System.out.println(linkedmap);  //按照插入的时间顺序输出
 }

统计单词出现的次数

/**统计单词出现的次数
  * 在TreeMap中,键值排序
  * Have 比 a 优先级要高 大写比小写高
  */
 public static void main(String[] args) {
  String text="Hello,Chicago! Have a nice day! Baby! Have fun this day.";
  TreeMap<String, Integer> map=new TreeMap<String, Integer>();
  String[] words=text.split("[ \n\t\r.,;:!?(){]");
  for (int i = 0; i < words.length; i++) {
   String key=words[i].toLowerCase();
   if(key.length()>0){
    if(map.get(key)==null){
     map.put(key, 1);
    }else{
     int value=map.get(key).intValue();
     map.put(key, value+1);
    }
   }
  }

  for(Map.Entry<String, Integer> m:map.entrySet()){
   System.out.println(m.getKey()+" \t "+m.getValue());
  }
 }

单元素和不可变的集合和图

<T> Set<T>
singleton(T o)

返回一个只包含指定对象的不可变 set。

static

<T> List<T>
singletonList(T o)

返回一个只包含指定对象的不可变列表。

static

<K,V> Map<K,V>
singletonMap(K key,
V value)

返回一个不可变的映射,它只将指定键映射到指定值。

<T> Collection<T>
unmodifiableCollection(Collection<?
extends T> c)

返回指定 collection 的不可修改视图。

static

<T> List<T>
unmodifiableList(List<?
extends T> list)

返回指定列表的不可修改视图。

static

<K,V> Map<K,V>
unmodifiableMap(Map<?
extends K,? extends V> m)

返回指定映射的不可修改视图。

static

<T> Set<T>
unmodifiableSet(Set<?
extends T> s)

返回指定 set 的不可修改视图。

static

<K,V> SortedMap<K,V>
unmodifiableSortedMap(SortedMap<K,?
extends V> m)

返回指定有序映射的不可修改视图。

static

<T> SortedSet<T>
unmodifiableSortedSet(SortedSet<T> s)

返回指定有序 set 的不可修改视图。

问题: Comparable接口和Comparator接口有啥区别?

Comparator位于包java.util下,而Comparable位于包   java.lang下。

都是用来实现集合中元素的比较、排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator
是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序。

Comparator
是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。

例如:

public class AbsComparator implements Comparator<Object> {
 public int compare(Object o1, Object o2) {
   int v1=Math.abs(((Integer)o1).intValue());
   int v2=Math.abs(((Integer)o2).intValue());
   return v1>v2?1:(v1==v2?0:-1);
 }
}
public static void main(String[] args) {
   Random random=new Random();
   Integer[] ints=new Integer[20];
   for (int i = 0; i < ints.length; i++) {
   ints[i]=new Integer(random.nextInt(100)*(random.nextBoolean()?1:-1));
  }
  System.out.println("使用内置方法排序");
  Arrays.sort(ints);
  System.out.println(Arrays.asList(ints));

  System.out.println("使用自定义排序");
  Arrays.sort(ints,new AbsComparator());
  System.out.println(Arrays.asList(ints));
 }

使用内置方法排序

[-99, -93, -91, -90, -55, -47, -39, 14, 26, 27, 27, 44, 53, 63, 65, 77, 81, 82, 84, 93]

使用自定义排序

[-4, -12, -18, 25, 40, 42, 44, -62, -71, -74, -77, -81, 82, -87, 87, 87, 90, -93, -94, 95]

而使用Comparable接口做比较

public class Person implements Comparable<Object> {
 public int compareTo(Object o) {
  // TODO Auto-generated method stub
  return 0;
 }
}

就可以自定义写比较方法

参照书籍《Java语言程序设计·进阶篇》 下一篇是编程练习题

2015年6月5日19:42:49

我是菜鸟,我在路上。

时间: 2024-10-12 08:01:43

java集合框架22的相关文章

我所理解Java集合框架的部分的使用(Collection和Map)

所谓集合,就是和数组类似--一组数据.java中提供了一些处理集合数据的类和接口,以供我们使用. 由于数组的长度固定,处理不定数量的数据比较麻烦,于是就有了集合. 以下是java集合框架(短虚线表示接口,长虚线表示抽象类,实线表示类,箭头表示实现接口或者继承)(在网络上找的图,不知道原作者,侵权请联系我删除)(总之,关系很复杂,所以不用记得这个图,只是用来吓吓人而已的). 下面贴上个人理解之精简版之Collection(集)和Map(地图?暂且这么理解吧),话说思维导图蛮好用,以下是两幅思维导图

Java集合框架(一)

Java集合框架结构图完整版 在完整版的结构图中Collection集合和Map下有许多未实现的抽象类(AbstractCollection.AbstractMap等等).下面整理一个简化版的,去除了一些不常用的子类和中间的一些抽象类. Java集合框架结构图简化版 说集合之前先来讲讲对象数组: 对象数组: 数组可以储存基本类型和引用类型,储存引用类型的数组叫对象数组(案例:用数组储存10个Animal类对象) 集合(Collection): a)集合的由来: Java语言是面对对象语言,需要操

[转载]Java集合框架的常见面试题

http://www.jfox.info/40-ge-java-ji-he-lei-mian-shi-ti-he-da-an 整理自上面链接: Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点.这里,我列出了一些关于Java集合的重要问题和答案. 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用, Java1.2提出了囊括所有集

Java集合框架中List接口的简单使用

Java集合框架可以简单的理解为一种放置对象的容器,和数学中的集合概念类似,Java中的集合可以存放一系列对象的引用,也可以看做是数组的提升,Java集合类是一种工具类,只有相同类型的对象引用才可以放到同一个集合中,否则是不能放进去的: 集合可以对元素进行简单快速的查找.插入.删除操作 某些集合可以有<key value>映射的关系 数组的长度是固定的,而集合的长度是跟随元素的个数动态变化的,灵活性和扩展性都比数组更加优越 数组只能存放基本类型的数据,而集合存放的是对象引用类型的 数组只能通过

解析java集合框架

在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(Java Collection Framework). Java程序员在具体应用时,不必考虑数据结构和算法实现细节,只需要用这些类创建出来一些对象,然后直接应用就可以了.这样就大大提高了编程效率. Java类集框架的优势:        1) 这种框架是高性能的.对基本类集(动态数组,链接表,树和散列表)的实现是高效率的.一般很少

第10篇-JAVA 集合框架-JAVA 泛型

第10篇-JAVA 集合框架-JAVA 泛型 每篇一句 :所有的不甘,都是因为还心存梦想 初学心得: 不是每件事都注定会成功,但是每件事都值得一试 (笔者:JEEP/711)[JAVA笔记 | 时间:2017-04-15| JAVA 集合框架/JAVA 泛型 ] 1.JAVA 集合框架概念 通俗的说,集合就是一个存放数据的容器,准确的说,就是放数据对象引用的容器 数组和集合都是容器,有何不同? 数组长度固定,集合长度可变 数组只能存放相同类型的数据,集合可以存放不同类型的数据 数组可存放简单数据

Java集合框架之List接口

在上一篇Java集合框架之Collection接口中我们知道List接口是Collection接口的子接口,List接口对Collection进行了简单的扩充,List接口中的元素的特点为有序,可重复,允许null值,因为List继承了Collection接口,所以继承自Collection接口中的方法不再赘述,从List接口中的方法来看,List接口主要是增加了面向位置的操作,允许在指定位置上对集合中的元素进行操作,同时增加了一个能够双向遍历线性表的新列表迭代器ListIterator.下面介

黑马程序员------Java集合框架学习总结

Java培训.Android培训.iOS培训..Net培训.期待您的交流 一.综述 所有集合类都位于java.util包下.集合中只能保存对象(保存对象的引用变量).(数组既可以保存基本类型的数据也可以保存对象). Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些接口或实现类. 二.Collection接口 Collction: List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引.

【JAVA集合框架之工具类】

一.概述 JAVA集合框架中有两个很重要的工具类,一个是Collections,另一个是Arrays.分别封装了对集合的操作方法和对数组的操作方法,这些操作方法使得程序员的开发更加高效. public class Collections extends Object 全类名:java.util.Collections public class Arrays extends Object 全类名:java.util.Arrays 二.Collections类. 1.Collections.sort