集合类型操作

list的遍历

package com.miracle.luna.lambda;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author Miracle Luna
 * @Date 2019/6/9 23:36
 * @Version 1.0
 */
public class ListLambda {
    public static void main(String[] args) {
        List<String> items = new ArrayList<>();

        items.add("A");
        items.add("B");
        items.add("C");

        // 普通for循环遍历
        System.out.println("第一种遍历方式:普通for循环遍历 List 集合");
        for (int i = 0; i < items.size(); i++) {
            System.out.println(items.get(i));
        }

        // 增强for循环遍历
        System.out.println("\n第二种遍历方式:增强for循环遍历 List 集合");
        for (String item : items) {
            System.out.println(item);
        }

        // Lambda 表达式遍历(JDK 1.8)
        System.out.println("\n第三种遍历方式:Lambda 表达式遍历 List 集合");
        items.forEach(item->{
            System.out.println(item);
        });

        // Lambda 表达式遍历(JDK 1.8)
        System.out.println("\n第四种遍历方式:Lambda 表达式遍历 List 集合");
        items.forEach(System.out::println);


        // 普通for循环遍历,判断判断是否包含字符串“C”
        System.out.println("\n第一种判断方式:普通for循环遍历,判断是否包含字符串“C”");
        for (int i = 0; i < items.size(); i++) {
            if ("C".equals(items.get(i))){
                System.out.println(items.get(i));
            }
        }

        // 增强for循环遍历,判断判断是否包含字符串“C”
        System.out.println("\n第二种判断方式:增强for循环遍历,判断是否包含字符串“C”");
        for (String item : items) {
            if ("C".equals(item)){
                System.out.println(item);
            }
        }

        // Lambda 表达式 判断是否包含字符串“C”(JDK 1.8)
        System.out.println("\n第三种判断方式:Lambda 表达式,判断是否包含字符串“C”");
        items.forEach(item->{
            if ("C".equals(item)){
                System.out.println(item);
            }
        });

        // Lambda 表达式 判断是否包含字符串“C”(JDK 1.8)
        System.out.println("\n第四种判断方式:Lambda 表达式,判断是否包含字符串“C”");
        items.stream().filter(s->s.contains("C")).forEach(System.out::println);

       } }

使用迭代器的方式

import java.util.ArrayList;

public class Demo03 {

  public static void main(String[] args) {

   ArrayList<News> list = new ArrayList<News>();
    
   list.add(new News(1,"list1","a"));
   list.add(new News(2,"list2","b"));
   list.add(new News(3,"list3","c"));
   list.add(new News(4,"list4","d"));
   
     Iterator<News> iter = list.iterator();
     while (iter.hasNext()) {
            News s = (News) iter.next();
            System.out.println(s.getId()+"  "+s.getTitle()+"  "+s.getAuthor());
    }
  }
}    

 list泛型的具体操作

(1).list中添加,获取,删除元素;

添加方法是:.add(e);  

获取方法是:.get(index);  

删除方法是:

remove(index); 按照索引删除;  

remove(Object o); 按照元素内容删除;

List<String> person=new ArrayList<>();
            person.add("jackie");                                   
            person.add("peter");            
            person.add("annie");    
            person.add("martin");   
            person.add("marry");               
            person.remove(3);   //.remove(index)
            person.remove("marry"); //.remove(Object o)
             
            String per="";
            per=person.get(1);
            System.out.println(per);                
            for (int i = 0; i < person.size(); i++) {
                System.out.println(person.get(i)); 
            }

list中根据索引将元素数值改变(替换);

.set(index, element); 和 .add(index, element); 的不同;

String a="白龙马", b="沙和尚", c="八戒", d="唐僧", e="悟空";
            List<String> people=new ArrayList<>();
            people.add(a);
            people.add(b);
            people.add(c);
            people.set(0,d); //.set(index,element);  
            people.add(1,e);   //.add(index,element) 
           //增强for循环遍历list
            for(String str:people){
                System.out.println(str);
            }

.判断list是否为空;

//空则返回true,非空则返回false
if (person.isEmpty()) {
    System.out.println("空的");
}else {
    System.out.println("不是空的");
}

其他

package test
 
object listDemo {
  def main(args: Array[String]): Unit = {
    val list: List[String] = List("a", "b" ,"a")
    //为列表预添加元素
    println("A" +: list)
    //在列表开头添加元素
    println("c" :: list)
    //在列表开头添加指定列表的元素
    println(List("d","e") ::: list)
    //复制添加元素后列表
    println(list :+ "1")
    //将列表的所有元素添加到 StringBuilder
    val sb = new StringBuilder("f")
    println(list.addString(sb))
    //指定分隔符
    println(list.addString(sb,","))
    //通过列表索引获取元素
    println(list.apply(0))
    //检测列表中是否包含指定的元素
    println(list.contains("a"))
    //将列表的元素复制到数组中,在给定的数组xs中填充该列表的最多为长度(len)元素,从start位置开始。
    val a = Array('a', 'b', 'c')
    val b : Array[Char] = new Array(5)
    a.copyToArray(b,0,1)
    b.foreach(println)
    //去除列表的重复元素,并返回新列表
    println(list.distinct)
    //丢弃前n个元素,并返回新列表
    println(list.drop(1))
    //丢弃最后n个元素,并返回新列表
    println(list.dropRight(1))
    //从左向右丢弃元素,直到条件p不成立
    println(list.dropWhile(_.equals("a")))
    //检测列表是否以指定序列结尾
    println(list.endsWith(Seq("a")))
    //判断是否相等
    println(list.head.equals("a"))
    //判断列表中指定条件的元素是否存在,判断l是否存在某个元素
    println(list.exists(x=> x == "a"))
    //输出符号指定条件的所有元素
    println(list.filter(x=> x.equals("a")))
    //检测所有元素
    println(list.forall(x=> x.startsWith("b")))
    //将函数应用到列表的所有元素
    list.foreach(println)
    //获取列表的第一个元素
    println(list.head)
    //从指定位置 from 开始查找元素第一次出现的位置
    println(list.indexOf("b",0))
    //返回所有元素,除了最后一个
    println(list.init)
    //计算多个集合的交集
    println(list.intersect(Seq("a","b")))
    //检测列表是否为空
    println(list.isEmpty)
    //创建一个新的迭代器来迭代元素
    val it = list.iterator
    while (it.hasNext){
      println(it.next())
    }
    //返回最后一个元素
    println(list.last)
    //在指定的位置 end 开始查找元素最后出现的位置
    println(list.lastIndexOf("b",1))
    //返回列表长度
    println(list.length)
    //通过给定的方法将所有元素重新计算
    list.map(x=> x+"jason").foreach(println)
    //查找最大元素
    println(list.max)
    //查找最小元素
    println(list.min)
    //列表所有元素作为字符串显示
    println(list.mkString)
    //使用分隔符将列表所有元素作为字符串显示
    println(list.mkString(","))
    //列表反转
    println(list.reverse)
    //列表排序
    println(list.sorted)
    //检测列表在指定位置是否包含指定序列
    println(list.startsWith(Seq("a"),1))
    //计算集合元素之和,这个地方必须是int类型,如果是string直接报错
    //println(list.sum)
    //返回所有元素,除了第一个
    println(list.tail)
    //提取列表的前n个元素
    println(list.take(2))
    //提取列表的后n个元素
    println(list.takeRight(1))
    //列表转换为数组
    println(list.toArray)
    //返回缓冲区,包含了列表的所有元素
    println(list.toBuffer)
    //List 转换为 Map
    val arr = Array(("jason", 24), ("jim", 25))
    arr.toMap.foreach(println)
    //List 转换为 Seq
    println(list.toSeq)
    //List 转换为 Set
    println(list.toSet)
    //列表转换为字符串
    println(list.toString())
  }
}

set集合的三种遍历方式

1.利用迭代器进行 ,迭代遍历:
Set<Object> sets = new HashSet<Object>();
Iterator<Object> it = set.iterator();
while (it.hasNext()) {
  String str = (String)it.next();
  System.out.println(str);
}

2.for循环遍历:
for (String str : sets) {
      System.out.println(str);
}

3.Set<Object> set = new HashSet<Object>();

foreach循环遍历:
for (Object obj: sets) {
      if(obj instanceof Integer){
                int aa= (Integer)obj;
             }else if(obj instanceof String){
               String aa = (String)obj
             }
              ……..
}

ArrayList实现原理要点概括
参考文献: 
http://zhangshixi.iteye.com/blog/674856l 
https://www.cnblogs.com/leesf456/p/5308358.html

ArrayList是List接口的可变数组非同步实现,并允许包括null在内的所有元素。
底层使用数组实现
该集合是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍,这种操作的代价很高。
采用了Fail-Fast机制,面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险
remove方法会让下标到数组末尾的元素向前移动一个单位,并把最后一位的值置空,方便GC
LinkedList实现原理要点概括
参考文献: 
1.http://www.cnblogs.com/ITtangtang/p/3948610.htmll 
2.https://www.cnblogs.com/leesf456/p/5308843.html

LinkedList是List接口的双向链表非同步实现,并允许包括null在内的所有元素。
底层的数据结构是基于双向链表的,该数据结构我们称为节点
双向链表节点对应的类Node的实例,Node中包含成员变量:prev,next,item。其中,prev是该节点的上一个节点,next是该节点的下一个节点,item是该节点所包含的值。
它的查找是分两半查找,先判断index是在链表的哪一半,然后再去对应区域查找,这样最多只要遍历链表的一半节点即可找到
HashMap实现原理要点概括
参考文献:http://zhangshixi.iteye.com/blog/672697 
参考文献:http://blog.csdn.net/lizhongkaide/article/details/50595719

HashMap是基于哈希表的Map接口的非同步实现,允许使用null值和null键,但不保证映射的顺序。
底层使用数组实现,数组中每一项是个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树,这样减少链表查询时间。
HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Node对象。HashMap底层采用一个Node[]数组来保存所有的key-value对,当需要存储一个Node对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Node时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Node。
HashMap进行数组扩容需要重新计算扩容后每个元素在数组中的位置,很耗性能
采用了Fail-Fast机制,通过一个modCount值记录修改次数,对HashMap内容的修改都将增加这个值。迭代器初始化过程中会将这个值赋给迭代器的expectedModCount,在迭代过程中,判断modCount跟expectedModCount是否相等,如果不相等就表示已经有其他线程修改了Map,马上抛出异常
Hashtable实现原理要点概括
参考文献:http://blog.csdn.net/zheng0518/article/details/42199477

Hashtable是基于哈希表的Map接口的同步实现,不允许使用null值和null键
底层使用数组实现,数组中每一项是个单链表,即数组和链表的结合体
Hashtable在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。
synchronized是针对整张Hash表的,即每次锁住整张表让线程独占
ConcurrentHashMap实现原理要点概括
参考文献:http://blog.csdn.net/zheng0518/article/details/42199477

ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。
它使用了多个锁来控制对hash表的不同段进行的修改,每个段其实就是一个小的hashtable,它们有自己的锁。只要多个并发发生在不同的段上,它们就可以并发进行。
ConcurrentHashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。
与HashMap不同的是,ConcurrentHashMap使用多个子Hash表,也就是段(Segment)
ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使用传统的技术,如HashMap中的实现,如果允许可以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的。
HashSet实现原理要点概括

HashSet是Set接口的典型实现,HashSet按照Hash算法来存储集合中的元素。存在以下特点:

  • 不能保证元素的顺序,元素是无序的
  • HashSet不是同步的,需要外部保持线程之间的同步问题
  • 集合元素值允许为null
HashSet的底层通过HashMap实现的,而HashMap在1.7之前使用的是数组+链表实现,在1.8+使用的数组+链表+红黑树实现。其实也可以这样理解,HashSet的底层实现和HashMap使用的是相同的方式,因为Map是无序的,因此HashSet也无法保证顺序。HashSet的方法也是借助HashMap的方法来实现的。

list,map,set的区别  
list,map,set的区别 (首先假定小猪都是同一个细胞克隆出来的)
List = 排成一长队的小猪  
Map = 放在一个个,有房间号的屋子里面的一群小猪  
Set = 一群小猪贴上号,然后赶到一个猪圈里

Hashset 它不保证集合的迭代顺序;特别是它不保证该顺序恒久不变。
LinkedHashSet定义了迭代顺序,即按照将元素插入到集合中的顺序(插入顺序)进行迭代。

参考文献:http://zhangshixi.iteye.com/blog/673789l

LinkedHashMap继承于HashMap,底层使用哈希表和双向链表来保存所有元素,并且它是非同步,允许使用null值和null键。
基本操作与父类HashMap相似,通过重写HashMap相关方法,重新定义了数组中保存的元素Entry,来实现自己的链接列表特性。该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而构成了双向链接列表。
LinkedHashSet实现原理要点概括
参考文献:http://zhangshixi.iteye.com/blog/673319l

对于LinkedHashSet而言,它继承与HashSet、又基于LinkedHashMap来实现的。LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同。

 

posted @ 2019-06-25 13:57  一心二念  阅读(222)  评论(0编辑  收藏  举报