集合-Collection,Map待续

Posted songzongyuan-java

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合-Collection,Map待续相关的知识,希望对你有一定的参考价值。

集合嵌套之ArrayList嵌套ArrayList

eg.

自定义Person类,成员变量name,age私有,有参无参,get(),set(),覆写toString()

import java.util.ArrayList;
import com.xxx.bean.Person;
public class Demo3_ArrayLIstArrayList {
    /*
     * 集合嵌套之ArrayList嵌套ArrayList 有一个group: 分为两个小组 g1 和 g2
     */
    public static void main(String[] args) {
        ArrayList<ArrayList<Person>> group = new ArrayList<>();

        ArrayList<Person> g1 = new ArrayList<>();
        g1.add(new Person("李小璐", 32));
        g1.add(new Person("马苏", 30));
        g1.add(new Person("杨幂", 30));

        ArrayList<Person> g2 = new ArrayList<>();
        g2.add(new Person("贾乃亮", 32));
        g2.add(new Person("孔令辉", 30));
        g2.add(new Person("刘恺威", 30));

        group.add(g1);
        group.add(g2);

        for (ArrayList<Person> g : group) { // 使用增强for循环嵌套增强for循环来遍历
            for (Person p : g) {
                System.out.println(p);
            }
            System.out.println();
        }
    }
}

HashSet存储字符串和自定义对象并遍历

遍历:没有索引,不能用.size() getIndex()遍历;不能用普通for循环,普通for循环i代表索引;可以用增强for循环,因为Set体系是Collection子类,Collection里面有Iterator迭代器,而增强for循环底层依赖的是迭代器。(只要能用迭代器迭代的,就可以用增强for循环遍历)。

 

如何保证存储自定义对象保证元素唯一?

重写equals()方法,但是没有被调用,因为每次传入一个对象,会调用父类的hashCode(),

每个对象返回的hashcode值都不相同,所以都存进来了。因此,还要重写hashCode()方法,hashCode返回值是一个数,正数代表右边,负数代表左边,0不存。当hashcode值相等的时候,才会调用equals方法。

如何减少调用equals()方法,提高代码的运行效率。将hashCode返回值为变量。

 

最终版:用自带的,同时重写equals()和hasnCode()  快捷键alt+shift+s  +h

eg

import java.util.HashSet;
import com.xxx.bean.Person;//Person类省略

public class Demo1_HashSet {
    public static void main(String[] args) {
        //demo1();
        HashSet<Person> hs = new HashSet<>();
        hs.add(new Person("张三", 23));
        hs.add(new Person("张三", 23));
        hs.add(new Person("李四", 24));
        hs.add(new Person("李四", 24));
        hs.add(new Person("李四", 24));
        hs.add(new Person("李四", 24));
        
        //System.out.println(hs.size());
        System.out.println(hs);
    }

    private static void demo1() {
        HashSet<String> hs = new HashSet<>();
        hs.add("c");
        boolean b1 = hs.add("a");
        boolean b2 = hs.add("a");
        hs.add("b");
        hs.add("d");
        
        System.out.println(hs);
//        System.out.println(b1);
//        System.out.println(b2);
        
        for (String string : hs) {            
            System.out.println(string);
        }
    }
}

LinkedHashSet的概述和使用

LinkedHashSet是HashSet子类,底层哈希算法实现和链表结构实现。

特点:与HashSet相比,它可以存取有序。

 

day23

 

练习:

1.  编写一个程序,获取10个1至20的随机数,要求随机数不能重复。并把最终的随机数输出到控制台。

分析:

1.随机数,创建随机数对象Random

2.创建一个set集合对象,可以自动去除重复

3.10个随机数 while,如果集合中的随机数不到10,就一直添加到集合

4.遍历集合,打印输出到控制台

import java.util.HashSet;
import java.util.Random;

public class Test1 {
    public static void main(String[] args) {
        // 1.随机数,创建随机数对象Random
        Random r = new Random();
        // 2.创建一个set集合对象,可以自动去除重复
        HashSet<Integer> hs = new HashSet<>();
        // 3.10个随机数 while,如果集合中的随机数不到10,就一直添加到集合
        while (hs.size() < 10) {
            System.out.println("添加前 size = " + hs.size());
            int num = r.nextInt(20) + 1;
            hs.add(num); // 自动装箱
            System.out.println("添加后 size = " + hs.size());
            System.out.println();
        }
        // 4.遍历集合,打印输出到控制台
        for (Integer integer : hs) {
            System.out.println(integer);
        }
    }
}

2. 使用Scanner从键盘读取一行输入,去掉其中重复字符, 打印出不同的那些字符

        分析:

        1.键盘录入Scanner

        2.用String line 来接收键盘录入,将字符串转换成字符数组

        3.去除重复,创建set集合,将数组中的每一个字符存储到set集合中,自动去除重复

        4.遍历集合,输出打印

eg.

import java.util.HashSet;
import java.util.Scanner;

public class Test2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String line = sc.nextLine();
        char[] arr = line.toCharArray();
        
        HashSet<Character> hs = new HashSet<>();
        
        for(char c: arr) {
            hs.add(c);        
        }
        
        for(Character ch : hs) {
            System.out.print(ch);
        }        
    }
}

3. 将集合中的重复元素去掉

     分析:

     1.定义一个list集合,存储重复的元素

     2.定义一个方法,去除集合中的重复元素

     3.输出打印list集合

eg.

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

public class Test3 {
    public static void main(String[] args) {
        // 1.定义一个list集合,存储重复的元素
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("b");
        list.add("b");
        list.add("c");
        list.add("c");
        list.add("c");
        list.add("c");
        
        System.out.println(list);      //没去重
        //2.定义一个方法,去除集合中的重复元素
        getSingle(list);
        //3.输出打印list集合
        System.out.println(list);     //去重
    }    
    /*
     * 去除集合中的重复元素
     * 1.void
     * 2.List<String> list
     * 
     * 分析:
     * 1.去除重复:创建一个set集合
     * 2.将list集合中的所有元素添加到set集合中,自动去除重复
     * 3.将list集合清空
     * 4.将set集合中的所有元素添回到list
     */
    public static void getSingle(List<String> list) {
        HashSet<String> hs = new HashSet<>();
        hs.addAll(list); //去除重复
        list.clear();
        list.addAll(hs);
    }
}

  在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复

  分析:

  1.定义list集合存储无序并重复的字符串

  2.定义一个方法,让其有序并保留重复

  3.遍历list集合

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

public class Test4 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("ccc");
        list.add("ccc");
        list.add("aaa");
        list.add("aaa");
        list.add("zuikc");
        list.add("bbb");
        list.add("bbb");
        list.add("fff");
        list.add("aaa");
        
        //2.定义一个方法,让其有序并保留重复
        sort(list);
        
        //3.遍历list集合
        System.out.println(list);
    }
    
    /*
     * 定义一个方法,让其有序并保留重复
     * 1.返回值类型 void
     * 2.参数列表 List<String> list
     * 
     * 1.要排序,创建TreeSet集合对象,传入比较器(按照比较器排序)
     * 2.将list集合中的所有元素添加到TreeSet集合
     * 3.将list集合清空
     * 4.将set集合中保留重复有序的元素添回到list集合
     */
    public static void sort(List<String> list) {
        //1.要排序,创建TreeSet集合对象,传入比较器(按照比较器排序)        
        TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                int num = s1.compareTo(s2);        //首要条件比较的是内容
                return num == 0 ? 1 : num;      //保留重复:只要返回值变成非0数字即可
            }
        });

        //2.将list集合中的所有元素添加到TreeSet集合
        ts.addAll(list);
        //3.将list集合清空
        list.clear();
        //4.将set集合中保留重复有序的元素添回到list集合
        list.addAll(ts);                
    }
}

TreeSet

TreeSet存储Integer类型的元素并遍历

        TreeSet是用来对元素进行排序的(自然排序),同样也可以保证元素的唯一

        如果compareTo()方法的返回值是0,集合中只有一个元素

        如果compareTo()方法的返回值是正数,集合中的元素怎么存,就怎么取(正序排序)

        如果compareTo()方法的返回值是负数,集合中的元素倒序排序

自然顺序(Comparable)

        TreeSet类的add()方法中会把存入的对象提升为Comparable类型

        调用对象的compareTo()方法和集合中的对象比较

        根据compareTo()方法返回的结果进行存储

 

Personimplements  Comparable 重写compareTo()

import java.util.TreeSet;
import com.xxxx.bean.Person;

public class Demo1_TreeSet {
    public static void main(String[] args) {
        //demo1();
        //demo2();
        //按照姓名的长度排序
        TreeSet<Person>  ts = new TreeSet<>();
        ts.add(new Person("zhangsan", 23));
        ts.add(new Person("lisi", 13));
        ts.add(new Person("wangwu", 43));
        ts.add(new Person("aaaa", 53));
        ts.add(new Person("aaaa", 63));
        ts.add(new Person("zhaoliu", 33));
        
        System.out.println(ts);
    }

    private static void demo2() {
        TreeSet<Person>  ts = new TreeSet<>();
        ts.add(new Person("李四", 13));
        ts.add(new Person("张三", 23));
        ts.add(new Person("张三", 3));
//        ts.add(new Person("周七", 13));
        ts.add(new Person("王五", 43));
        ts.add(new Person("赵六", 33));
        
        System.out.println(‘张‘ + 0);  //unicode值
        System.out.println(‘李‘ + 0);
        System.out.println(‘王‘ + 0);
        System.out.println(‘赵‘ + 0);
        System.out.println(ts);
    }

    private static void demo1() {
        TreeSet<Integer> ts = new TreeSet<>();
        ts.add(3);
        ts.add(1);        //自动装箱
        ts.add(1);
        ts.add(2);
        ts.add(2);        
        System.out.println(ts);
    }
}
重写的compareTo
@Override
    //姓名的长度是首要条件 --> 姓名内容 ---> 年龄
    public int compareTo(Person o) {
        int length = this.name.length() - o.name.length();                //姓名的长度是首要条件
        int num = length == 0 ? this.name.compareTo(o.name) : length;   //姓名的内容是次要条件
        return num == 0 ? this.age - o.age : num;                        //年龄是次次要条件
    }
    
    /*//比较姓名
    @Override
    public int compareTo(Person o) {
        int num = this.name.compareTo(o.name);        //姓名是比较的主要条件
        return num == 0 ? this.age - o.age : num;   //年龄是比较的次要条件
    }*/
    
    
    /*@Override
    //比较年龄
    public int compareTo(Person o) {
        int num = this.age - o.age;      //年龄是比较的主要条件
        return num == 0 ? this.name.compareTo(o.name) : num ;  //姓名是比较的次要条件
    }*/

比较器顺序(Comparator)

        创建TreeSet的时候可以制定一个Comparator
        
如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
        add()
方法内部会自动调用Comparator接口中compare()方法排序
        
调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数

import java.util.Comparator;
import java.util.TreeSet;

public class Demo2_TreeSet {
    /*
     * TreeSet保证元素唯一和比较器排序的原理及代码实现
        * 需求:将字符串按照长度排序 
        * 
        * 比较器排序优先于自然排序
     */
    public static void main(String[] args) {
        TreeSet<String> ts = new TreeSet<>(new CompareByLen());  //传入比较器 Comparator c = new CompareByLen();
        ts.add("aaaaaaaaaaaaa");                 //父类引用指向子类对象:多态
        ts.add("z");
        ts.add("wc");
        ts.add("nba");
        ts.add("cba");
        
        System.out.println(ts);
    }
}

class CompareByLen /*extends Object*/ implements Comparator<String> {

    @Override
    public int compare(String s1, String s2) {
        int num = s1.length() - s2.length();        //长度是比较的首要条件
        return num == 0 ? s1.compareTo(s2) : num;    //内容是比较的次要条件
    }    
}

两种方式的区别

      TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)

        TreeSet如果传入Comparator, 就优先按照Comparator进行排序

 

在集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复。

分析:

           1.定义list集合存储无序并重复的字符串。

2.定义一个方法,让其有序并保留重复。

 

3.遍历list集合

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

public class Test4 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("ccc");
        list.add("ccc");
        list.add("aaa");
        list.add("aaa");
        list.add("zuikc");
        list.add("bbb");
        list.add("bbb");
        list.add("fff");
        list.add("aaa");
        
        //2.定义一个方法,让其有序并保留重复
        sort(list);
        
        //3.遍历list集合
        System.out.println(list);
    }
    
    /*
     * 定义一个方法,让其有序并保留重复
     * 1.返回值类型 void
     * 2.参数列表 List<String> list
     * 
     * 1.要排序,创建TreeSet集合对象,传入比较器(按照比较器排序)
     * 2.将list集合中的所有元素添加到TreeSet集合
     * 3.将list集合清空
     * 4.将set集合中保留重复有序的元素添回到list集合
     */
    public static void sort(List<String> list) {
    //1.要排序,创建TreeSet集合对象,传入比较器(按照比较器排序),匿名内部类
        TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                int num = s1.compareTo(s2);        //首要条件比较的是内容
                return num == 0 ? 1 : num;      //保留重复:只要返回值变成非0数字即可
            }
        });

        //2.将list集合中的所有元素添加到TreeSet集合
        ts.addAll(list);
        //3.将list集合清空
        list.clear();
        //4.将set集合中保留重复有序的元素添回到list集合
        list.addAll(ts);                
    }
}

从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入: helloworld 程序打印:dehllloorw

          分析:

          1.键盘录入Scanner

          2.要排序,创建TreeSet集合,又因为保留了重复的字符,传入比较器

          3.line接收键盘录入的字符串,line转换成字符数组,获取每一个字符

          4.遍历数组,将每一个字符存储到set集合中

 

          5.遍历set集合,打印输出每一个字符

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Test5 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");        
        TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() {
            @Override
            public int compare(Character c1, Character c2) {
                int num = c1.compareTo(c2);        //两者功能一样
//                int num = c1 - c2;                
                return num == 0 ? 1 : num;
            }
        });
        String line = sc.nextLine();
        char[] arr = line.toCharArray();
        for (char c : arr) {
            ts.add(c);        //自动装箱
        }
        
        for(Character ch : ts) {
            System.out.print(ch);
        }        
    }
}

程序启动后, 可以从键盘输入接收多个整数, 直到输入quit时结束输入. 把所有输入的整数倒序排列打印.

          分析:

          1.键盘录入Scanner

          2.排序,所以要创建TreeSet集合对象,又因为是倒序排序,传入比较器(按照倒序排序)

          3.接收多个整数,要用循环(无限循环);

          4.在循环中做判断:如果接收的是字符串quit,终止循环break;如果是数字字符串,将该字符串转换Integer存在set集合中

 

          5.遍历set集合,输出打印每一个int

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Test6 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数据:");        
        TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer i1, Integer i2) {
                //int num = i2 - i1;
                int num = i2.compareTo(i1);
                return num == 0 ? 1 : num;
            }            
        });
        
        while(true) {        //因为要录入不确定的个数,所以用无线循环
            String line = sc.nextLine();
            if("quit".equals(line)) {
                break;
            }            
            Integer i = Integer.parseInt(line);  //将数字字符串转换成int数
            ts.add(i);
        }
        
        for (Integer integer : ts) {
            System.out.println(integer);
        }
    }
}

迭代总结

1.List

     a.普通for循环, 使用get(int index)逐个获取      (Set没有,因为没有索引)

     b.调用iterator()方法得到Iterator, 使用hasNext()next()方法

     c.增强for循环, 只要可以使用Iterator的类都可以用

     d.Vector集合可以使用EnumerationhasMoreElements()nextElement()方法

2.Set

a.调用iterator()方法得到Iterator, 使用hasNext()next()方法

 b.增强for循环, 只要可以使用Iterator的类都可以用

 

3.普通for循环,迭代器,增强for循环不能在遍历的过程中删除 

 

     

 

/*

     * 去除集合中的重复元素

     * 1.void

     * 2.List<String> list

     *

     * 分析:

     * 1.去除重复:创建一个set集合

     * 2.list集合中的所有元素添加到set集合中,自动去除重复

     * 3.list集合清空

     * 4.set集合中的所有元素添回到list

     */

    publicstaticvoid getSingle(List<String> list) {

       HashSet<String> hs = new HashSet<>();

       hs.addAll(list); //去除重复

       list.clear();

       list.addAll(hs);

    }

}




以上是关于集合-Collection,Map待续的主要内容,如果未能解决你的问题,请参考以下文章

金蝶handler中 collection 代码片段理解

集合类(Collection和Map接口)简介

集合总结(Collection,List,Set,Map)(补充集合结构图的关系)

collection集合--Map

JAVA 基础之容器集合(Collection和Map)

Java--Collection和Map集合