list set map比较

1. List接口的特征:

    (1) 有顺序的。(2) 可重复的。(3) 存放不同的数据类型。

2. Set接口的特征:

    (1) 无顺序的。(2) 不可重复的。(3) 可以存放不同的数据类型。

3. SortedSet接口的特征:

    (1) 继承了Set接口。(2) 排好顺序的集合。(3) 不可重复的。(4) 只存放同类型的。

4. 类和接口关系:

    LinkedList、ArrayList、Vector类  ---实现--->    List接口

    HashSet类    ---实现--->   Set接口

    TreeSet类     ---实现--->   SortedSet接口

    HashMap、HashTable   ---实现--->  Map接口(HashTable有个子类Properties专门用来读取配置文件)

    TreeMap        ---实现--->   SortedMap接口

5. List实现类比较:

    (1) ArrayList:底层用数组来实现;查询效率高,添加删除慢。

    (2) LinkedList: 底层用双向链表来实现;查询效率低,添加删除快。

    (3) Vector:底层也用数组实现;它是一个线程安全的ArrayList;应用与多线程。

6. HashSet:

    (1) 它里面的数据没有下标的,所以不能用for循环来遍历,只能用Iterator(迭代器)。

    (2) 底层代码用"哈希表"来实现。

7. 一种比较奇怪的现象:

    HashSet set = new HashSet();

    set.add("hello"); 这个添加成功。

    set.add("hello"); 添加失败,因为Set是"不可重复的"。

    set.add(new String("hello")); 这个也没有添加成功!! 为什么?? 难道是因为"不同对象但equals相等的原因".

    所以就按照上面的思想"不同对象但equals相等的原因",继续写两个类,再添加两个同一Person类时,这两个Person类是不同对象但equals相同,但是结果却添加成功了。这个又是为什么??

     原因:哈希表它希望元素随机地等概率的分布在底层数组中。

              计算hashcode的步骤过程:

              (1) 调用Person的hashcode()方法(主要是指地址,因为两个Person类地址不一样,所以得到的int值不一样),得到int值。

              (2) int%总容器(求余),求余后得到一个值(这个值为下标)。

              (3) 冲突(若求出的余数相同则冲突),然后调用equals方法。

              这样就可以解释上面的原因了:

                   因为String有"池化思想"。它的"hello"和new String("hello")是在同一个池中,所以地址是一样的,这样就会发生"冲突",然后它又去调用equals方法,但是hello的equals都相等的。所以最后没有插进去!!

                    但是Person就不一样了,它的地址就不一样的,所以就没有发生冲突的。这样就不用equals了,直接可以插进去了!!

 

8. 往hashset类中添加对象时,一定要覆盖hashcode()方法和equals()方法。

 

9. Treeset类:底层是用二叉树来比较的。

    (1) 构造方法(自然排序)  。

    (2) 自己定义比较器来排序。

10. 两种比较方式来往Treeset里面添加数据。

     (1) 让类来实现java.lang包中的Comparable接口,然后实现其中的compareTo方法,只要compareTo方法返回值为0,则认为它们两个相同。代码如下:

public class Person implements Comparable{ String name; int age; public int compareTo(Object o){ Person p = (Person)o; return p.age-this.age; } } public class TreeSetTest2 { public static void main(String[] args) { TreeSet set = new TreeSet(); set.add(new Person("ZhangSan",25)); set.add(new Person("Lisi",28)); set.add(new Person("WangWu",25)); set.add(new Person("Lisi",20)); Iterator it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }

 (2)另外一种是:(用比较器,调用Treeset的第三个构造函数,要求传递一个比较器)定义一个内部类去实现java.util包中的Comparator接口。代码如下:

public class TreeSetTest3 { public static void main(String[] args) { TreeSet set = new TreeSet(new MyComparator()); set.add(new Student("Weiwei",20)); set.add(new Student("Linlong",22)); set.add(new Student("Huaxi",21)); set.add(new Student("Wuxi",18)); Iterator it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } } class MyComparator implements Comparator{ public int compare(Object o1,Object o2){ Student s = (Student)o1; Student s2 = (Student)o2; return s.age-s2.age; } }

 注意:如果经常变动的要用比较器比较合适,因为它可以用不同的构造方法,同时传递不同的对象来改变比较的。

          如果不经常变动的,则用实现Comparable接口。

 

11. Comparable(接口)              可比较的                java.lang

      Comparator(接口)              比较器                    java.util

      Iterable(接口)                     可迭代的                java.lang

      Iterator(接口)                     迭代器                    java.util

      要想用"迭代器"进行遍历,必须实现Iterable接口,才能用迭代器。

      在java.lang包中有Iterable接口,这个接口中有iterator()方法,因为ArrayList实现了Iterable接口,所以就实现了iterator()方法,但这个方法的返回类型是Iterator这个接口的实现类,则it为实现类对象的一个引用,所以调用其中的3个方法。

      Iterator it = list.iterator();

      while(it.hasNext()){

          Object o = it.next();

          System.out.println(o);

       }

 

12. Map接口:

    (1)方法:keySet();返回类型为所有的key的集合。

                 get(Object key);得到key所对应的值。

        这两个方法结合起来进行遍历。

HashMap map = new HashMap(); Set s = map.keySet(); Iterator it = s.iterator(); while(it.hasNext()){ Object key = it.next(); Object value = map.get(key); System.out.println(key+":"+value); }

 

 13.

HashSet set = new HashSet(); Iterator it = set.iterator(); while(it.hasNext()){ Object o = it.next(); System.out.print(o+" "); }

 

14.字符串的比较要用trim()和toLowerCase(),然后再indexOf来查找。

Set<Scene> sceneAllList = actor.getSceneCollection(); Iterator it = sceneAllList.iterator(); while(it.hasNext()){ Scene s = (Scene)it.next(); Set<SceneVideo> sceneVideoAllList = s.getSceneVideoCollection(); Iterator i = sceneVideoAllList.iterator(); while(i.hasNext()){ SceneVideo sceneVideo = (SceneVideo)i.next(); String strVideoUrl = sceneVideo.getVideoUrl(); String strPlaylistFile = sceneVideo.getPlaylistFile(); int indexUrl = strVideoUrl.trim().toLowerCase().indexOf(quality.trim().toLowerCase()); int indexPlay = strPlaylistFile.trim().toLowerCase().indexOf(quality.trim().toLowerCase()); if(indexUrl != -1 || indexPlay != -1){ sceneQualityList.add(s); } } }
将一个形如:Stting="asdsdfsdfasdasda"这样的字符串,计算出这个字符串的同种字符的个数,以及有多少种不同的字符?
String s="asdsdfsdfasdasda"; int differentCount = 0; Map<Character,Integer> map = new HashMap<Character,Integer>(); for(int i=0;i<s.length();i++){ Character c = new Character(s.charAt(i)); if(map.containsKey(c)){ map.put(c, map.get(c).intValue()+1); }else{ map.put(c, new Integer(1)); } } Iterator<Character> it = map.keySet().iterator(); while(it.hasNext()){ Character tmpc = it.next(); differentCount++; System.out.println(tmpc+"="+map.get(tmpc)); } System.out.println("differentCount="+differentCount);
 
 

Collection List Set Map 区别记忆

这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。
 
  有序否 允许元素重复否
Collection
List
Set AbstractSet
HashSet
TreeSet 是(用二叉树排序)
Map AbstractMap
使用key-value来映射和存储数据,Key必须惟一,value可以重复
HashMap
TreeMap 是(用二叉树排序)
 
 
 
List接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放到一个List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。前面说的Iterator只能对容器进行向前遍历,而ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。

Set接口也是Collection的一种扩展,而与List不同的时,在Set中的对象元素不能重复,也就是说你不能把同样的东西两次放入同一个Set容器中。它的常用具体实现有HashSet和TreeSet类。HashSet能快速定位一个元素,但是你放到HashSet中的对象需要实现hashCode()方法,它使用了前面说过的哈希码的算法。而TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具有相同的排序算法,那就不需要在每分别重复定义相同的排序算法,只要实现Comparator接口即可。集合框架中还有两个很实用的公用类:Collections和Arrays。Collections提供了对一个Collection容器进行诸如排序、复制、查找和填充等一些非常有用的方法,Arrays则是对一个数组进行类似的操作。


Map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一个Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。Map有两种比较常用的实现:HashMap和TreeMap。HashMap也用到了哈希码的算法,以便快速查找一个键,TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。键和值的关联很简单,用pub(Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lesliehu2158

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值