当前位置:   article > 正文

Java集合_java set next 后怎么

java set next 后怎么

1.集合与数组存储数据概述:
集合、数组都是对多个数据进行存储操作的结构,简称Java容器。
说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储。

2.数组存储的特点:
●一旦初始化以后,其长度就确定了。
数组一旦定义好,其元素的类型也就确定了。我们也就只能操作指定类型的数据了。                       比如::String[] arr,int[] arr1,object[] arr2。


3.数组存储的弊端:
●—旦初始化以后,其长度就不可修改。
●数组中提供的方法非常限,对于添加、删除、插入数据等操作,非常不便,同时效率不高。
●获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用
●数组存储数据的特点:有序、可重复。对于无序、不可重复的需求,不能满足。


4.集合存储的优点:
解决数组存储数据方面的弊端。

单列集合框架结构

collection接口:单列集合,用来存储一个一个的对象
List接口:存储序的、可重复的数据。-->“动态”数组
          ArrayList、LinkedList、Vector
Set接口:存储无序的、不可重复的数据-->高中讲的"集合”
     HashSet、 LinkedHashSet、 TreeSet

1.contains(Object obj):判断当前集合中是否包含obj

2.containsAll(Conllection coll):判断coll中的所有元素是否都存在于当前集合中。

3.remove(Object obj):从当前集合中移除obj元素。

4.removeAll(Conllection coll):从当前集合中移除coll中的所有元素。

5.retainALL(Conllection coll):交集:获取当前集合和coll集合的交集,并返回给当前集合

/***      Collection coll = Arrays.asList(123,456,789);

            coll.retainAll(coll);    system.out.println(coll);

***/

6.equals(Object obj):想要返回true,需要当前集合和形参集合的元素都相同。

7.hashCode():返回当前对象的哈希值。

8.集合 ---> 数组:toArray()。

9.iterator():返回Iterator接口的实例,用于遍历集合元素。

集合对象每次调用Iterator()方法兜得到一个全新的迭代器对象,默认游标都在第一个元素之前。

  1. public class CollectionTest {
  2. @Test
  3. public void test1() {
  4. Collection coll = new ArrayList();
  5. coll.add(123);
  6. coll.add(456);
  7. coll.add(789);
  8. coll.add("A");
  9. Iterator iterator = coll.iterator();
  10. /** 方式一:
  11. System.out.println(iterator.next());
  12. System.out.println(iterator.next());
  13. System.out.println(iterator.next());
  14. System.out.println(iterator.next());
  15. //报异常:NoSuchElementException
  16. System.out.println(iterator.next());
  17. 方式二:不推荐
  18. for (int i = 0; i < coll.size(); i++) {
  19. System.out.println(iterator.next());
  20. }
  21. **/
  22. // 方式三:
  23. while (iterator.hasNext()){
  24. System.out.println(iterator.next());
  25. }
  26. }
  27. @Test
  28. public void test2() {
  29. Collection coll = new ArrayList();
  30. coll.add(123);
  31. coll.add(456);
  32. coll.add(789);
  33. coll.add("A");
  34. // 删除集合中A
  35. Iterator iterator = coll.iterator();
  36. while (iterator.hasNext()) {
  37. Object obj = iterator.next();
  38. if ("A".equals(obj)) {
  39. iterator.remove();
  40. }
  41. }
  42. // 遍历集合
  43. iterator = coll.iterator();
  44. while (iterator.hasNext()) {
  45. System.out.println(iterator.next());
  46. }
  47. }
  48. }

集合元素的遍历操作,使用迭代器Iterator接口

1.内部的方法: hasNext()和next()
2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
3.内部定义了remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove()

测试中terator中的remove()
如果还未调用next()或在上一次调用next方法之后已经调用了remove方法/再调用remove都会报ILLegalstateException。
 

使用foreach循环遍历集合 ---Java5.0新特性

  1. public class ForeachTest {
  2. @Test
  3. public void test(){
  4. Collection coll = new ArrayList();
  5. coll.add(123);
  6. coll.add(456);
  7. coll.add(789);
  8. coll.add("A");
  9. // for(集合元素的类型 局部变量 :集合对象)
  10. for (Object obj : coll){
  11. System.out.println(obj);
  12. }
  13. }
  14. }

List接口概述
List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。
JDK API中List接口的实现类常用的有: ArrayList、 LinkedList和IVector。

常用方法:

1. void add(int index, Object ele): 在index位置插入eLe元素
2. boolean addAll(int index, Collection eles): M从index位置开始将eles中的所有元素添加进来
3. object get(int index): 获取指定index位置的元素,如果不存在,返回-1。
4. int indexOf(Object obj): 返回obj在集合中首次出现的位置,如果不存在,返回-1。
5. int lastIndexOf(Object obj): 返回obj在当前集合中末次出现的位置

6. object remove(int index): 移除指定index位置的元素,并返回此元素
7. 0bject set(int index, object ele): 设置指定index位置的元素为ele
8. List subList(int fromIndex, int toIndex): 返回从fromIndex到toIndex位置的子集合

  1. public class ArrayListTest {
  2. @Test
  3. public void test1() {
  4. ArrayList list = new ArrayList();
  5. list.add(123);
  6. list.add(456);
  7. list.add("A");
  8. list.add(new Person("jiejie"));
  9. System.out.println(list);
  10. // void add(int index, Object ele): 在index位置插入eLe元素
  11. list.add(1, "B");
  12. System.out.println(list);
  13. // boolean addAll(int index, Collection eles): M从index位置开始将eles中的所有元素添加进来
  14. List list1 = Arrays.asList(1, 2, 3);
  15. list.addAll(list1);
  16. // list.add(list1); //按照整体
  17. System.out.println(list.size());
  18. // object get(int index): 获取指定index位置的元素
  19. System.out.println(list.get(0));
  20. }
  21. @Test
  22. public void test2() {
  23. ArrayList list = new ArrayList();
  24. list.add(123);
  25. list.add(456);
  26. list.add("A");
  27. list.add(new Person("jiejie"));
  28. // int indexOf(Object obj): 返回obj在集合中首次出现的位置,如果不存在,返回-1。
  29. int index = list.indexOf(456);
  30. System.out.println(index);
  31. //
  32. // int lastIndexOf(Object obj): 返回obj在当前集合中末次出现的位置,如果不存在,返回-1。
  33. System.out.println(list.lastIndexOf(456));
  34. // object remove(int index): 移除指定index位置的元素,并返回此元素
  35. Object obj = list.remove(0);
  36. System.out.println(obj);
  37. // 0bject set(int index, object ele): 设置指定index位置的元素为ele
  38. list.set(1,"C");
  39. System.out.println(list);
  40. // List subList(int fromIndex, int toIndex): 返回从fromIndex到toIndex位置的子集合
  41. List subList = list.subList(1,3);
  42. System.out.println(subList);
  43. }
  44. }

  总结:常用方法

增:add(Object obj)

删:remove(int index) / remove(Object obj)

改:set(int index,Object ele)

查:get(int index)

插:add(int index,Object ele)

长度:size()

遍历:①Iterator迭代器遍历:

       Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next()); }

        ②增强for循环:

        for (Object obj : list){
             System.out.println(obj); }

        ③普通的循环

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

        

面试题::ArrayList、LinkedList、Vector三者的异同?

同:三个类都是实现了List接口,存储数据的特点相同:存储有序的、可重复的数据

不同:Collection接口: 单列集合,用来存储-一个一个的对象

        List接口: 存储有序的、可重复的数据。 -->“动态”数组,替换原有的数组

   ArrayList: 作为List接口的主要实现类;线程不安全的,效率高;底层使用0bject[] eLementData存储

   LinkedList: 对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储

   Vector:作为List接口的由老实现类;线程安全的,效率低;底层使用0bject[] elementData存储

面试题:remove方法

  1. @Test
  2. public void test(){
  3. List list = new ArrayList();
  4. list.add(1);
  5. list.add(2);
  6. list.add(3);
  7. updateList(list);
  8. System.out.println(list);
  9. }
  10. private void updateList(List list){
  11. list.remove(2); // 删除索引2 返回1 2
  12. // list.remove(new Integer(2)); //删除数字2 返回1 3
  13. }

        

 collection接口:单列集合,用来存储一个一个的对象
 Set接口:存储无序的、不可重复的数据
   HashSet:作为Set接口的主要实现类;线程不安全的;可以存储null值。
   LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历。
   TreeSet:可以按照添加对象的指定属性,进行排序。

1.Set接口中没有额外定义新的方法,使用的都是collection中声明过的方法。
2.要求:向Set中添加的数据,其所在的类一定要重写hashcode( )和equals()
   要求:重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码
           重写两个方法的小技巧:对象中用作equals()方法比较的 Field,都应该用来计算hashCode

一、set:存储无序的、不可重复的数据
 以Hashset为例说明:
 1.无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值
 2.不可重复性:保证添加的元素按照equals()判断时,不能返回true.即:相同的元素只能添加一个。

二、添加元素的过程:以Hashset为例:
我们向HashSet中添加元素a,首先调用元素α所在类的hashCode()方法,计算元素a的哈希值,
此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已经有元素:
如果此位置上没有其他元素,则元素α添加成功。--->情况1
如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
如果hash值不相同,则元素α添加成功。--->情况2
如果hash值相同,进而需要调用元素a所在类的equLas()方法:
equals()返回true,元素α添加失败
equals()返回false,则元素α添加成功。--->情况3


对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上数据以链表的方式存储。
jdk 7 ︰元素α放到数组中,指向原来的元素。
jdk 8 ∶原来的元素在数组中,指向元素α总结:七上八下

HashSet底层:数组+链表的结构。

  1. @Test
  2. public void test1(){
  3. Set set = new HashSet();
  4. set.add(123);
  5. set.add(456);
  6. set.add("B");
  7. set.add("A");
  8. set.add(new Person("jiejie"));
  9. Iterator iterator = set.iterator();
  10. while (iterator.hasNext()){
  11. System.out.println(iterator.next());
  12. }

LinkedHashSet的使用
LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据。

优点:对于频繁的遍历操作,LinkedHashSet效率高于Hashset

  1. @Test
  2. public void test2(){
  3. Set set = new LinkedHashSet();
  4. set.add(123);
  5. set.add(456);
  6. set.add("B");
  7. set.add("A");
  8. set.add(new Person("jiejie"));
  9. Iterator iterator = set.iterator();
  10. while (iterator.hasNext()){
  11. System.out.println(iterator.next());
  12. }
  13. }

TreeSet

1.向Treeset中添加的数据,要求是相同类的对象。
2.两种排序方式:自然排序(实现Comparable接和定制排序
3.自然排序中,比较两个对象是否相同的标准为: compareTo()返回e.不再是equals().

  1. @Test
  2. public void test1() {
  3. TreeSet set = new TreeSet();
  4. //失败:不能添加不同类的对象
  5. // set.add(123);
  6. // set.add(456);
  7. // set.add("B");
  8. // set.add("A");
  9. // set.add(new Person("jiejie"));
  10. set.add(123);
  11. set.add(456);
  12. set.add(-123);
  13. Iterator iterator = set.iterator();
  14. while (iterator.hasNext()) {
  15. System.out.println(iterator.next());
  16. }
  17. }
  1. // 按照名字从小到大排序 -this的话则为从大到小
  2. @Override
  3. public int compareTo(Object o) {
  4. if (o instanceof Person){
  5. Person person = (Person) o;
  6. return this.name.compareTo(person.name);
  7. }else {
  8. throw new RuntimeException("输入的类型不匹配");
  9. }
  10. }
  11. //自然排序
  12. @Test
  13. public void test2() {
  14. TreeSet set = new TreeSet();
  15. set.add(new Person("flandre"));
  16. set.add(new Person("jiejie"));
  17. set.add(new Person("scout"));
  18. set.add(new Person("viper"));
  19. set.add(new Person("meiko"));
  20. Iterator iterator = set.iterator();
  21. while (iterator.hasNext()) {
  22. System.out.println(iterator.next());
  23. }
  24. }
  1. //定制排序
  2. @Test
  3. public void test3() {
  4. Comparator com = new Comparator() {
  5. //按照年龄从小到大排序
  6. @Override
  7. public int compare(Object o1, Object o2) {
  8. if (o1 instanceof Person && o2 instanceof Person){
  9. Person p1 = (Person) o1;
  10. Person p2 = (Person) o2;
  11. return Integer.compare(p1.getAge(),p2.getAge());
  12. }else {
  13. throw new RuntimeException("输入的数据类型不匹配");
  14. }
  15. }
  16. };
  17. TreeSet set = new TreeSet(com);
  18. set.add(new Person("flandre",23));
  19. set.add(new Person("jiejie",20));
  20. set.add(new Person("scout",23));
  21. set.add(new Person("viper",21));
  22. set.add(new Person("meiko",23));
  23. Iterator iterator = set.iterator();
  24. while (iterator.hasNext()) {
  25. System.out.println(iterator.next());
  26. }
  27. }

关于Set的面试题:

  1. //面试题1
  2. @Test
  3. public void test4(){
  4. HashSet set = new HashSet();
  5. Person p1 = new Person(1001, "AA");
  6. Person p2 = new Person(1002, "BB");
  7. set.add(p1);
  8. set.add(p2);
  9. p1.name = "CC";
  10. set.remove(p1);//在set中删除 先找哈希值 没有就不删
  11. System.out.println(set);
  12. set.add(new Person(1001,"CC"));
  13. System.out.println(set);
  14. set.add(new Person(1001,"AA"));
  15. System.out.println(set);
  16. //[Person{id='1002', name='BB'}, Person{id='1001', name='CC'}]
  17. //[Person{id='1002', name='BB'}, Person{id='1001', name='CC'}, Person{id='1001', name='CC'}]
  18. //[Person{id='1002', name='BB'}, Person{id='1001', name='CC'}, Person{id='1001', name='CC'}, Person{id='1001', name='AA'}]
  19. }

一:Map: 双列数据,存储key-value对的数据 。  ---类似于高中的函数: y = f(x)
    HashMap:作为Map的主要实现类;线程不安全的,效率高;存储nulL的key和value
           LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
           原因:在原有的HashMap底层结构基础上,添加了- -对指针,指向前一个和后 一个元    素。对于频繁的遍历操作,此类执行效率高于HashMap。
     TreMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序
底层使用红黑树
     Hashtable:作为古老的实现类;线程安全的,效率低;不能存储nulL的key和value
        Properties:常用来处理配置文件。key和value都是String类型

二、Map结构的理解:
Map中的key:无序的、不可重复的,使用Set 存储所有的key ---> key所在的类要重写equals()和hashCode() ( 以HashMap为例)
Map中的value:无序的、可重复的,使用Collection存储所有 的value --->value所在的类要 重写equaLs()
一个键值对::key-value构成了一个Entry对象。
Map中的entry:无序的、不可重复的,使用set存储所有的entry

三、HashMap的底层实现原理?以jdk7为例说明:面试题
HashMap map = new HashMap( ) :
在实例化以后,底层创建了长度是16的一维数组Entry[] table。
可能已经执行过多itput
map.put(key1, vaLue1):
首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。
如果此位置上的数据为空,此时的key1-value1添加成功。---- 情况1
如果此位置上的数据不为空,(意味着此位置上存在一个或多 个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值:
   如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1 添加成功。----情况2
   如果key1的哈希值和已经存在的某一个数 据(key2-vaLue2)的哈希值相同,继续比较:调用key1 所在类的equaLs(key2)
        如果equals().返回false:此时key1-value1添加成功。---- 情况3
        如果equals()返回true:使用value1替换value2。


补充:关于情况2和情况3:此时key1-value1 和原来的数据以链表的方式存储。


在不断的添加过程中,会涉及到扩容问题,默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。

jdk8相较于jdk7在底层实现方面的不同:
1. new HashMap():底层没有创建-一个长度为16的数组
2. jdk 8底层的数组是::Node[],而非Entry[]
3. 首次调用put()方法时,底层创建长度为16的数组
4. jdk7底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树。

四、 Map 中定义的方法:
添加、删除、修改操作:
Object put(Object key, object value):将指定key-vaLue 添加到(或修改)当前map对象中
void putAll(Map m):将m中的所有key-value对存放到当前map中
object remove(object key):移除指定key的key-value对, 并返回value
void clear():清空当前map中的所有数据


元素查询的操作:
0bject get(0bject key):获取指定key对应的value
boolean containsKey(Object key):是否包含指定的key
boolean containsValue(0bject vaLue):是否包含指定的value
int size():返回map中key-value对的个数
boolean isEmpty():判断当前map是否为空
boolean equals(object obj):判断当前map和参数对象obj是否相等


元视图操作的方法:
Set keySet():返回所有key构成的Set集合
Collection values():返回所有value构成的Collection集合
Set entrySet():返回所有key-value对构成的Set集合

Properties:常用来处理配置文件。key 私value都是String类型

  1. public class mapTest {
  2. @Test
  3. public void test1(){
  4. HashMap map = new HashMap();
  5. map.put("AA",123);
  6. map.put(44,123);
  7. map.put("BB",456);
  8. //遍历所有的key集:keySet()
  9. Set set = map.keySet();
  10. Iterator iterator = set.iterator();
  11. while (iterator.hasNext()){
  12. System.out.println(iterator.next());
  13. }
  14. //遍历所有的value集:values()
  15. Collection values = map.values();
  16. for (Object obj : values){
  17. System.out.println(obj);
  18. }
  19. //遍历所有的key-value:entrySet()
  20. //方式一
  21. Set entrySet = map.entrySet();
  22. Iterator iterator1 = entrySet.iterator();
  23. while (iterator1.hasNext()){
  24. Object obj = iterator1.next();
  25. //entrySet集合中的元素都是entry
  26. Map.Entry entry = (Map.Entry) obj;
  27. System.out.println(entry.getKey()+"--->"+entry.getValue());
  28. }
  29. //方式二
  30. Set keySet = map.keySet();
  31. Iterator iterator2 = keySet.iterator();
  32. while (iterator2.hasNext()){
  33. Object key = iterator2.next();
  34. Object value = map.get(key);
  35. System.out.println(key+"-----"+value);
  36. }
  37. }
  38. }

  1. //自然排序
  2. @Test
  3. public void test1() {
  4. TreeMap map = new TreeMap();
  5. Person p1 = new Person("flandre",23);
  6. Person p2 = new Person("jiejie",20);
  7. Person p3 = new Person("scout",23);
  8. Person p4 = new Person("viper",21);
  9. Person p5 = new Person("meiko",23);
  10. map.put(p1,94);
  11. map.put(p2,99);
  12. map.put(p3,95);
  13. map.put(p4,96);
  14. map.put(p5,95);
  15. Set entrySet = map.entrySet();
  16. Iterator iterator1 = entrySet.iterator();
  17. while (iterator1.hasNext()){
  18. Object obj = iterator1.next();
  19. Map.Entry entry = (Map.Entry) obj;
  20. System.out.println(entry.getKey()+"--->"+entry.getValue());
  21. }
  22. }
  23. //定制排序
  24. @Test
  25. public void test2(){
  26. TreeMap map = new TreeMap(new Comparator() {
  27. @Override
  28. public int compare(Object o1, Object o2) {
  29. if (o1 instanceof Person && o2 instanceof Person){
  30. Person p1 = (Person)o1;
  31. Person p2 = (Person)o2;
  32. return Integer.compare(p1.getAge(),p2.getAge());
  33. }
  34. throw new RuntimeException("输入的类型不匹配");
  35. }
  36. });
  37. Person p1 = new Person("flandre",23);
  38. Person p2 = new Person("jiejie",20);
  39. Person p3 = new Person("scout",23);
  40. Person p4 = new Person("viper",21);
  41. Person p5 = new Person("meiko",23);
  42. map.put(p1,94);
  43. map.put(p2,99);
  44. map.put(p3,95);
  45. map.put(p4,96);
  46. map.put(p5,95);
  47. Set entrySet = map.entrySet();
  48. Iterator iterator1 = entrySet.iterator();
  49. while (iterator1.hasNext()){
  50. Object obj = iterator1.next();
  51. Map.Entry entry = (Map.Entry) obj;
  52. System.out.println(entry.getKey()+"--->"+entry.getValue());
  53. }
  54. }
  55. // 按照名字从大到小排序,年龄从小到大
  56. @Override
  57. public int compareTo(Object o) {
  58. if (o instanceof Person){
  59. Person person = (Person)o;
  60. int compare = -this.name.compareTo(person.name);
  61. if (compare != 0){
  62. return compare;
  63. }else {
  64. return Integer.compare(this.age,person.age);
  65. }
  66. }else {
  67. throw new RuntimeException("输入的类型不匹配");
  68. }

总结:常用方法:
添加:put(0bject key, object vaLue)
删除:remove(0bject key)
修改:put(object key, Object value )
查询:get(object key)
长度:size()
遍历:keySet() / values() / entrySet()

面试题:Collection 和 Collections 的区别?

collection:存储单列数据的一个集合接口,常见的子接口为list、set
collections:一个操作collection的工具类

Collection的常用方法:

排序操作:(均为static方法 )
●reverse(List):反转List 中元素的顺序
●shuffle(List):对List集合元素进行随机排序
●sort(List):根据元素的自然顺序对指定List集合元素按升序排序
●sort(List,Comparator):根据指定的Comparator产生的顺序对List集合元素进行排序
●swap(List,int, int):将指定list集合中的i处元素和j处元素进行交换

查找、替换
●Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
●Object max(Collection,Comparator):根据Comparator指定的顺序,返回给定集合中的最大元素
●Object min(Collection)
●Object min(Collection,Comparator)
●int frequency(CollectionI Object):返回指定集合中指定元素的出现次数
●void copy(List dest,List src):将src中 的内容复制到dest中
●boolean replaceAll(List list,Object oldVal, Object newVal):使用新值替换List对象的所有旧值

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/858835
推荐阅读
相关标签
  

闽ICP备14008679号