第八篇.wjj

集合体系:

Collection:单列集合,每个元素只代表一个值

注:Collection<E>是接口,同时拥有很多子接口,例List<E>,Set<E>接口

List<E>下面实现类(Arrylist<E>,LinkedList<E>等)

Set<E>下面实现类(TreeSet<E>,HashSet<E>(子类LinkedHashSet)等)

List系列集合:添加的元素是有序,可重复,有索引。

Arrylist<E>,LinkedList<E>:有序,可重复,有索引

Set系列集合:添加的元素是无序,不重复,无索引。

HashSet<E>:无序,不重复,无索引

LinkedHashSet:有序,不重复,无索引

TreeSet<E>:按照大小默认升序排序,不重复,无索引

注:集合中存储的是对象地址

Collection常用方法

public bollean add(E e)添加元素,成功返回true
public  void clear()清空集合中的元素
public  bollean  isEmpty 判断集合是否为空,空返回true
public int size获取集合大小
public bollean contains(objjrc)判断集合中是否包含某个元素
public  bollean remove (E e)删除元素,如果有多个元素默认删除第一个出现的
public Object[]  toArray()把集合转为数组

 Collection<String> a1 = new ArrayList<>();
        //添加元素,成功返回true
        a1.add("aa");
        a1.add("bb");
        a1.add("cc");
        a1.add("bb");
        //清空集合中的元素
//        a1.clear();
        System.out.println(a1);
        //判断集合是否为空,空返回true
        System.out.println(a1.isEmpty());
        //判断集合中是否包含某个元素
        System.out.println(a1.contains("aa"));
        //获取集合大小
        System.out.println(a1.size());
        //删除元素,如果有多个元素默认删除第一个出现的
        a1.remove("bb");
        System.out.println(a1);
        //把集合转为数组
        Object[]arr=a1.toArray();
      String[] b= a1.toArray(new String [a1.size()]);//此数组类型数据只能是String
        Collection<String> a12= new ArrayList<>();
        a12.add("ccc");
        a12.add("ccc");
        a12.add("ccc");
        //将a12数据存储到a1;
        a1.addAll(a12);
        System.out.println(a1);

迭代器:用于遍历集合的专用方式,例Iterator

注:数组没有迭代器

Collection集合获取迭代器的方法

方法名称说明
Interator<E> iterator()返回集合中的迭代对象,该迭代器对象默认指向集合第一个元素

Iterator迭代器中的常用方式

方法名称说明
boolean hasNext()询问当前位置是否有元素存在,存在返回true
E next

获取当前位置的元素,并同时将迭代器对象指向下一个元素处

  Collection<String> a=new ArrayList<>();
        a.add("姓名");
        a.add("班级");
        a.add("年龄");
        a.add("身高");
        a.add("姓名");
        a.add("体重");
        Iterator<String> it = a.iterator();//alt+enter可以补全代码
        System.out.println(it.next());
        System.out.println(it.next());
        System.out.println(it.next());
        System.out.println(it.next());
        System.out.println(it.next());
        System.out.println(it.next());
//        System.out.println(it.next());多余数组长度会出异常
        while (it.hasNext()) {
            String e= it.next();
            System.out.println(e);
        }

增强for循环

可以用于遍历数组或集合

注:增强for遍历数组,本质上就是迭代器遍历集合的简化写法

格式:

for(元素的数据类型 变量名:数组或者集合名称){

}

  Collection<String> b=new ArrayList<>();
        b.add("姓名");
        b.add("班级");
        b.add("年龄");
        b.add("身高");
        b.add("姓名");
        int arr[]={1,2,3,4};
        //快捷键数组名或集合名加.for
        for (String s : b) {
            System.out.println(s);

        }
        for (int i : arr) {
            System.out.println(i);

Lambda表达式遍历集合

方法名称说明
default void forEach (Consumer<?super T> action结合Lambda遍历集合

  Collection<String> a=new ArrayList<>();
        a.add("星期一");
        a.add("星期二");
        a.add("星期三");
        a.add("星期四");
        a.add("星期五");
        System.out.println(a);
//        a.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });
//        a.forEach((String s)-> {
//                System.out.println(s);
//        });
//        a.forEach( s-> System.out.println(s));
          a.forEach( System.out::println);

List

public void add(int index,E element)在某个索引位置插入元素
public E remove(int index)根据索引删除元素,返回被删除的元素
public E get (int index返回集合中指定位置的元素
public E set(int index,E element)修改索引位置处的元素,修改成功后返回原来的数据

list还可以使用for循环遍历

  for (int i = 0; i < b.size(); i++) {
            System.out.println(b.get(i));

ArrayList集合底层原理(基于数组实现)

查询快,增删慢

利用无参构造器构造的集合,会在底层创建一个默认长度为0的数组,

当开始添加数据,会创建新的长度为10的数组,当长度为10的数组存

满,会扩容到15,再装满,新建数组长度为实际长度。

linkedList集合底层原理(基于双链表实现)

特点:查询慢,增删快,但对于首尾元素增删改查快

public void addFirst(E e)在列表开头插入指定元素
public void addLast(E e)将指定元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素

两者适用场景

ArrayList:适合根据索引查数据,或者数据量不大

不适合数据大,且需要频繁的增删的场景

LinkedList:

1.可以用于设计队列(先进先出,后进后出)

 LinkedList<String> queue=new LinkedList<>();
       queue.addLast("1");
        queue.addLast("2");
        queue.addLast("3");
        queue.addLast("4");
        //queue.add("1"); 与这样加一样
        for (int i = queue.size()-1; i >=0; i--) {
            System.out.println(queue.removeFirst());
        }

2.用于设计栈(先进后出,后进先出)

 LinkedList<String> stack=new LinkedList<>();
        stack.addFirst("1");
        stack.addFirst("2");
        stack.addFirst("3");
        stack.addFirst("4");
        for (int i = stack.size()-1; i >=0; i--) {
            System.out.println(stack.removeFirst());
        }

HashSet:基于哈希表实现

哈希表=数组+链表+红黑树

HashSet是一种增删改查数据,性能都较好的数据结构(使用hashCode取哈希值)

注:两个内容一样的学生对象存入HashSet集合中去,HashSet不能去重复(因为不同对象的哈希值不一样),要是想去重复,需要重写hashCode和euqals方法

  @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Students students = (Students) o;
        return age == students.age && Double.compare(students.height, height) == 0 && Objects.equals(name, students.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, height);
    }

LinkedHashSet:有序,不重复,无索引

也基于哈希表,但比hashSet多一个双链表

TreeSet:可排序序,不重复,无索引

对于数值型按数字大小排序

对于字符串型,按照首字符的编号排序

对于自定义类型如Student对象,无法直接排序

因此自定义比较规则

法一:让自定义的类实现Comparable接口,重写里面的comparableTo

方法来指定比较规则

 class Students implements Comparable<Students>{
 @Override
    public int compareTo(Students o) {
        return this.age-o.age;
    }

法二:通过调用TreeSet集合有参构造器,可以设置Comparator对象(比较器对象,用于指定比较规则)

 Set<Students> k=new TreeSet<>(( o1, o2)->o1.getAge()-o2.getAge());

简化的并发修改异常:使用迭代器遍历集合时,又同时删除数据,出现的错误

增强for循环出现这种情况无法解决

Iterator可以解决

 Iterator<String>it=li.listIterator();
        while (it.hasNext()) {
            String name = it.next();
            if (name.contains("李")) {
                it.remove();//自己的方法
            }
        }

或者使用for循环解决

 for (int i = 0; i < li.size(); i++) {
            String name1 = li.get(i);
            if (name1.contains("李")) {
                li.remove(name1);
                i--;//
            }
        }

Collection其他知识:

可变参数:一种特殊形参,定义在方法、构造器的形参列表里,

格式是:数据类型..参数名称;

  public static void b(int...b) {
        System.out.println(2);
    }


可变参数的特点和好处

特点:可以不传数据给它;可以传-一个或者同时传多个数据给它;也可以传一 个数组给它。

好处:常常用来灵活的接收数据。

  public static void main(String[] args) {
        b();
        a(10);
        a(10,20,30);
        a(1,new int []{10,20,30});

    }
    public static void b(int...b) {
        System.out.println(2);
    }
    public static void a(int a,int...b){
        System.out.println(b.length);
        System.out.println(Arrays.toString(b));

    }

可变参数的注意事项:

可变参数在方法内部就是一个数组;

一个形参列表中可变参数只能有一个;

可变参数必须放在形参列表的最后面

collections:一个用来操作集合的工具类

方法名称说明
public static <T> boolean addAll(Collection<? super T> C, T... elements)给集合批量添加元素
public static void shuffle(List<?> list)打乱List集合中的元素顺序
public static <T> void sort(List<T> list)对List集合中的元素进行升序排序
public static <T> void sort(List<T> list, Comparatorc? super T> c)对List集合中元素,按照比较器对象指定的规则进行排序

public class first {
    public static void main(String[] args) {

//        public static <T> boolean addAll(Collection<? super T> C, T... elements)给集合批量添加元素
        List<String> a=new ArrayList<>();
        Collections.addAll(a,"1","4","6");
        System.out.println(a);


//        public static void shuffle(List<?> list)打乱List集合中的元素顺序
        Collections.shuffle(a);
        System.out.println(a);
//        public static <T> void sort(List<T> list) 对List集合中的元素进行升序排序
        List<Integer>b=new ArrayList<>();//!!!!需要是List而不是其他
        b.add(1);
        b.add(3);
        b.add(4);
        b.add(9);
        b.add(1);
        Collections.sort(b);
        System.out.println(b);
        List<Movies> movie=new ArrayList<>();
        movie.add(new Movies("绿皮书",9.2,"a"));
        movie.add(new Movies("阿甘正传",8.6,"a"));
        movie.add(new Movies("肖申克的救赎",8.9,"c"));
        Collections.sort(movie,(o1,o2)->Double.compare(o1.getScore(),o2.getScore()));
//是o1.getScore(),o2.getScore()
        System.out.println(movie);

//        public static <T> void sort(List<T> list, Comparatorc? super T> c)对List集合中元素,按照比较器对象指定的规则进行排序




    }
}
class Movies implements Comparable<Movies>{//<Movies>要有
    private String name;
    private double score;
    private String actor;

    @Override
    public int compareTo(Movies o) {
//        return Double.compare(this.Score-o.Score);错误写法
        return  Double.compare(this.score,o.score);
    }

场景选择

1、如果希望记住元素的添加顺序,需要存储重复的元素,又要频繁的根据索引查询数据?

  用ArrayList集合 (有序、可重复、有索引) ,底层基于数组的。 (常用 )

2、如果希望记住元素的添加顺序,且增删首尾数据的情况较多?

 用LinkedList集合 (有序、可重复、有索引),底层基于双链表实现的。

3.如果不在意元素顺序,也没有重复元素需要存储,只希望增删改查都快?

 用HashSet集合 (无序,不重复,无索引),底层基于哈希表实现的。( 常用)

4.如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快?

 用LinkedHashSet集合 (有序,不重复,无索引),底层基 于哈希表和双链表。

5.如果要对元素进行排序,也没有重复元素需要存储?且希望增删改查都快?

 用TreeSet集合, 基于红黑树实现。

Map:双列集合,每个元素包含两个值(键值对)

Map系列集合的特点都是由键决定,值只是一个附属品,值不做要求

HashMap<E>(由键决定特点):无序,不重复,无索引(用的最多)

LinkedHashMap(由键决定特点):有序,不重复,无索引

TreeMap<E>(由键决定特点):按照大小默认升序排序,不重复,无索引

  Map<String,Integer> a=new HashMap<>();//无序,不重复,相同后者覆盖前者,无索引
        Map<String,Integer>a=new LinkedHashMap<>();//有序,不重复,相同后者覆盖前者,无索引
        a.put("a",11);
        a.put("d",12);
        a.put("ac",16);
        a.put("a",15);
        a.put(null,null);
//TreeMap排序依照第一个变量

 Map<String,Integer> c=new TreeMap<>();//可排序,不重复,相同后者覆盖前者,无索引
        c.put("a",11);
        c.put("d",12);
        c.put("ac",16);
        c.put("a",15);
//        c.put(null,null);不可以有
        System.out.println(c);//a=15, ac=16, d=12
        Map<Integer,String> c1=new TreeMap<>();
      c1.put(16,"a");
      c1.put(17,"ac");
      c1.put(16,"c");
      c1.put(18,"d");
        System.out.println(c1);//16=c, 17=ac, 18=d

Map的常用方法

方法名称说明
public V put(K key,V value)添加元素
public int size()获取集合的大小
public void clear( )清空集合
public boolean isEmpty()判断集合是否为空,为空返回true,反之
public V get(Object key)根据键获取对应值
public V remove(Object key)根据键删除整个元素
public boolean containsKey(Object key)判断是否包含某个键
public boolean containsValue(Object value) 判断是否包含某个值
public Set<K> keySet( )获取全部键的集合
public Collection<V> values( )获取Map集合的全部值

  public static void main(String[] args) {
//        public V put(K key,V value)添加元素
        Map<String,Integer> a = new HashMap<>();
        a.put("a",11);
        a.put("d",12);
        a.put("ac",16);
        a.put("a",15);
        a.put(null,null);
//        public int size() 获取集合的大小
        System.out.println(a.size());
//        public void clear( ) 清空集合
//        a.clear();
//        public boolean isEmpty() 判断集合是否为空,为空返回true,反之
        System.out.println(a.isEmpty());
//        public V get(Object key)根据键获取对应值
        int k=a.get("a");
        System.out.println(k);//15
        System.out.println(a.get(""));//返回null,没有则返回null
//        public V remove(Object key)根据键删除整个元素
        a.remove("d");
        System.out.println(a);
//        public boolean containsKey(Object key)判断是否包含某个键返回false或true
        System.out.println(a.containsKey("a"));//true
//        public boolean containsValue(Object value) 判断是否包含某个值返回false或true
        System.out.println(a.containsValue(11));
//        public Set<K> keySet( ) 获取全部键的集合
        Set<String> aaaaa=a.keySet();
        System.out.println(aaaaa);
//        public Collection<V> values( ) 获取Map集合的全部值
        Collection<Integer> bbbbbb=a.values();
        System.out.println(bbbbbb);
//        把其他Map集合数据导入自己集合
        Map<Integer,String> a1=new LinkedHashMap<>();
        a1.put(11,"c");
        a1.put(12,"b");
        a1.put(16,"b");
        a1.put(11,"a");
        a1.put(null,null);
        Map<Integer,String> c1=new TreeMap<>();
        c1.put(16,"a");
        c1.put(17,"ac");
        c1.put(16,"c");
        c1.put(18,"d");
        a1.putAll(c1);
        System.out.println(a1);
//

Map集合的遍历方式

problems集合

使用前看是否有import java.util.Collection;
无则alt+enter

 Collection<String> a1 = new ArrayList<>();

2.

List<String> queue=new LinkedList<>();//这样不能使用LinkedList的方法removeFirst()
 LinkedList<String> queue=new LinkedList<>();//这样才可以

3.使用for循环删除数组时注意:如果for循环的判断条件是

数组名.size()时需要注意,因为删除了数组中的数据,所以

数组长度也会变化,可以将原先数组长度1用一个数表示出来,

或者倒着删除

    //法一:  
        int a= queue.size() ;
        for (int i = 0; i < a; i++) {

         System.out.println(queue.removeFirst());
        //法二:
         for (int i = queue.size()-1; i >=0; i--) {
            System.out.println(queue.removeFirst());
        }//切记倒着遍历时不要忘了改成i-- ;

  • 39
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mshkkhhgybzlc

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

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

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

打赏作者

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

抵扣说明:

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

余额充值