当前位置: 首页 > article >正文

Java 集合一口气讲完!(上)||o(*°▽°*)o|Ю [有人吗?]

Java 集合遍历

Java集合教程 - Java集合遍历

在Java Collections Framework中,不同类型的集合使用不同类型的数据结构以不同的方式存储它们的元素。

一些集合对它们的元素有排序,有些没有。集合框架提供了遍历集合的以下方法:

  • 使用迭代器
  • 使用for-each循环
  • 使用forEach()方法

使用迭代器

集合提供了一个迭代器来遍历其所有元素。

迭代器可以对集合执行以下三个操作:

  • 检查是否有尚未访问的元素。
  • 访问集合中的下一个元素。
  • 删除集合的最后访问元素。

Java中的迭代器是 Iterator< E> 接口的一个实例。

我们可以使用Collection接口中的iterator()方法获取集合的迭代器。

以下代码创建一个字符串列表,并获取列表的迭代器:

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

public class Main {
  public static void main(String[] args) {
    // Create a list of strings
    List<String> names = new ArrayList<>();

    // Get an iterator for the list
    Iterator<String> nameIterator = names.iterator();
  }
}

迭代器< E> 接口包含以下方法:

boolean hasNext()
E next()
default void  remove()
default void  forEachRemaining(Consumer<? super  E> action)

如果集合中有更多元素要迭代, hasNext()方法将返回true。否则,它返回false。

next()方法返回集合中的下一个元素。我们应该在调用 next()方法之前调用 hasNext()方法。如果没有, next()方法会抛出NoSuchElementException异常。

例子

通常, hasNext() next()方法在循环中一起使用。以下代码使用迭代器打印列表的所有元素:

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

public class Main {
  public static void main(String[] args) {
    // Create a list of strings
    List<String> names = new ArrayList<>();
    names.add("A");
    names.add("B");
    names.add("C");
    // Get an iterator for the list
    Iterator<String> nameIterator = names.iterator();
    // Iterate over all elements in the list
    while (nameIterator.hasNext()) {
      // Get the next element from the list
      String name = nameIterator.next();
      System.out.println(name);
    }

  }
}

上面的代码生成以下结果。

remove()方法删除 next()方法最后返回的元素。每次调用next()方法只能调用一次 remove()方法。

如果对于每个 next()方法或在第一次调用next()之前被多次调用 remove()方法,它会抛出一个 IllegalStateException异常。

 remove()方法的支持是可选的。remove()方法可能会抛出一个 UnsupportedOperationException 异常。

例2

以下代码使用迭代器遍历列表的所有元素,并使用remove()方法删除该元素。

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

public class Main {
  public static void main(String[] args) {
    // Create a list of strings
    List<String> names = new ArrayList<>();
    names.add("A");
    names.add("B");
    names.add("C");

    Iterator<String> nameIterator = names.iterator();
    // Iterate over all elements in the list
    while (nameIterator.hasNext()) {
      // Get the next element from the list
      String name = nameIterator.next();
      System.out.println(name);
      nameIterator.remove();
    }
    System.out.println(names);
  }
}

上面的代码生成以下结果。

例3

forEachRemaining()方法对集合中尚未由迭代器访问的每个元素执行操作。

action指定为 Consumer 

以下代码显示如何打印列表的所有元素。

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

public class Main {
  public static void main(String[] args) {
    // Create a list of strings
    List<String> names = new ArrayList<>();
    names.add("A");
    names.add("B");
    names.add("C");

    Iterator<String> nameIterator = names.iterator();
    nameIterator.forEachRemaining(System.out::println);
  }
}

上面的代码生成以下结果。

迭代器注意事项

迭代器是一次性对象。我们不能重置迭代器,它不能被重用。

要再次遍历同一集合的元素,请通过调用集合的iterator()方法来创建一个新的Iterator。

使用for-each循环

我们可以使用for-each循环遍历集合的元素。

我们可以使用for-each循环遍历任何实现类实现Iterable接口的集合。

for-each循环的一般语法如下:

Collection<T> yourCollection  = ;
for(T  element : yourCollection)  {
}

在幕后,for-each循环获取迭代器并调用hasNext()和next()方法。

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

public class Main {
  public static void main(String[] args) {
    // Create a list of strings
    List<String> names = new ArrayList<>();
    names.add("A");
    names.add("B");
    names.add("C");

    for (String name : names) {
      System.out.println(name);
    }

  }
}

上面的代码生成以下结果。

for-each注意事项

for-each循环有几个限制。

我们不能使用for-each循环从集合中删除元素。

以下代码将抛出ConcurrentModificationException异常:

List<String> names = get   a  list;
for(String name : names)  {
    names.remove(name);// Throws a  ConcurrentModificationException 
}

对于for-each循环,我们没有办法从集合的中间开始。

for-each循环不提供访问先前访问的元素的方式。

使用forEach()方法

Iterable接口包含一个新的 forEach(Consumer action)方法。

该方法遍历所有元素并应用操作。

forEach()方法在从 Collection 接口继承的所有集合类型中都可用。

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

public class Main {
  public static void main(String[] args) {
    // Create a list of strings
    List<String> names = new ArrayList<>();
    names.add("A");
    names.add("B");
    names.add("C");

    names.forEach(System.out::println);
  }
}

上面的代码生成以下结果。

Java Set集合

Java集合教程 - Java Set集合

Set 表示唯一对象的集合。集合中元素的排序是不相关的。

集合框架提供三种类型的集合:

  • 数学集
  • 排序集
  • 导航集

数学集

Set 接口对数学中的一组进行建模。集合是唯一元素的集合。

Java最多允许一个Set中的一个空元素。 Set 中元素的排序并不重要。

Java不保证 Set 中元素的排序。

当循环遍历 Set 的所有元素时,你得到 Set 中的每个元素一次。

集合框架提供 HashSet 类作为实现为设置接口。

以下代码显示了如何创建一个Set并向其添加元素。 当向集合添加重复元素时,它们将被忽略。

如果比较它们,则在集合中的两个元素被认为是相等的使用 equals()方法返回true。

import java.util.HashSet;
import java.util.Set;

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

    Set<String> s1 = new HashSet<>();

    // Add a few elements
    s1.add("HTML");
    s1.add("CSS");
    s1.add("XML");
    s1.add("XML"); // Duplicate

    // Create another set by copying s1
    Set<String> s2 = new HashSet<>(s1);
    // Add a few more elements 
    s2.add("Java"); 
    s2.add("SQL");
    s2.add(null); // one null is fine
    s2.add(null); // Duplicate

    System.out.println("s1: " + s1);
    System.out.println("s1.size(): " + s1.size());

    System.out.println("s2: " + s2);
    System.out.println("s2.size(): " + s2.size());
  }
}

上面的代码生成以下结果。

LinkedHashSet

集合框架提供 LinkedHashSet 类作为 Set 接口的另一个实现类。

HashSet 不保证顺序元素。 LinkedHashSet 在插入元素时保持元素顺序。

import java.util.LinkedHashSet;
import java.util.Set;

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

    Set<String> s1 = new LinkedHashSet<>();
    s1.add("A");
    s1.add("B");
    s1.add("C");
    s1.add("D");
    System.out.println("LinkedHashSet: " + s1);


  }
}

上面的代码生成以下结果。

集合操作

我们可以对集合执行并集,交集和差分运算。

// Union  of  s1  and  s2  will be  stored in s1 
s1.add(s2);

// Intersection of  s1  and  s2  will be  stored in s1 
s1.retainAll(s2);

// Difference of  s1  and  s2  will be  stored in s1 
s1.removeAll(s2);

在集合操作期间,修改s1。要保持原始设置不变,请在操作之前复制:

Set  s1Unions2  = new HashSet(s1); // Make a  copy  of  s1
s1Unions2.addAll(s2);

要测试集合s1是否是另一个集合s2的子集,请使用s2.containsAll(s1)方法。

import java.util.HashSet;
import java.util.Set;

public class Main {
  public static void main(String[] args) {
    Set<String> s1 = new HashSet<>();
    s1.add("HTML");
    s1.add("CSS");
    s1.add("XML");

    Set<String> s2 = new HashSet<>();
    s2.add("Java");
    s2.add("Javascript");
    s2.add("CSS");

    System.out.println("s1: " + s1);
    System.out.println("s2: " + s2);

    performUnion(s1, s2);
    performIntersection(s1, s2);
    performDifference(s1, s2);
    testForSubset(s1, s2);
  }

  public static void performUnion(Set<String> s1, Set<String> s2) {
    Set<String> s1Unions2 = new HashSet<>(s1);
    s1Unions2.addAll(s2);
    System.out.println("s1 union  s2: " + s1Unions2);
  }

  public static void performIntersection(Set<String> s1, Set<String> s2) {
    Set<String> s1Intersections2 = new HashSet<>(s1);
    s1Intersections2.retainAll(s2);
    System.out.println("s1 intersection  s2: " + s1Intersections2);
  }

  public static void performDifference(Set<String> s1, Set<String> s2) {
    Set<String> s1Differences2 = new HashSet<>(s1);
    s1Differences2.removeAll(s2);

    Set<String> s2Differences1 = new HashSet<>(s2);
    s2Differences1.removeAll(s1);

    System.out.println("s1 difference s2: " + s1Differences2);
    System.out.println("s2 difference s1: " + s2Differences1);
  }

  public static void testForSubset(Set<String> s1, Set<String> s2) {
    System.out.println("s2 is  subset s1: " + s1.containsAll(s2));
    System.out.println("s1 is  subset s2: " + s2.containsAll(s1));
  }

}

上面的代码生成以下结果。

Java 排序集 

Java集合教程 - Java排序集

排序集是在其元素上有排序的集合。

SortedSet 接口表示Java集合中的排序集合框架。

排序集中的元素可以按照自然顺序排序可比较的接口或使用 Comparator 

SortedSet 必须知道如何在添加元素时对其元素进行排序检查两个接口:

  • 如果它的元素实现了Comparable接口,它将使用compareTo()方法来排序项目。 我们可以称之为自然顺序排序。
  • 我们可以传递一个比较器做自定义排序。

如果指定了 Comparator ,则 Comparator 是用于排序并忽略 Comparable 接口。

TreeSet 类是Collection框架中SortedSet接口的一个实现。

例子

在下面的代码中,我们添加 String 对象 SortedSet 

String 类实现 Comparable 接口。

SortedSet将使用 Comparable 接口及其 compareTo()方法对String值进行排序。

import java.util.SortedSet;
import java.util.TreeSet;

public class Main {
  public static void main(String[] args) {
    // Create a sorted set of some names
    SortedSet<String> sortedNames = new TreeSet<>();
    sortedNames.add("Java");
    sortedNames.add("SQL");
    sortedNames.add("HTML");
    sortedNames.add("CSS");

    // Print the sorted set of names
    System.out.println(sortedNames);
  }

}

上面的代码生成以下结果。

例2

以下代码显示如何存储在 SortedSet 中的人物对象列表。

我们不能添加Person类的对象在SortedSet中,除非我们还提供一个 Comparator 对象因为Person类不实现 Comparable 接口。

以下代码创建一个 SortedSet 的使用 Comparator 的人使用他们的名字排序的人:

SortedSet<Person> personsSortedByName = new TreeSet<>(Comparator.comparing(Person::getName));

该代码使用方法引用来创建用于创建Comparator对象的lambda表达式。

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

public class Main {
  public static void main(String[] args) {
    SortedSet<Person> personsById = new TreeSet<>(
        Comparator.comparing(Person::getId));

    personsById.add(new Person(1, "X"));
    personsById.add(new Person(2, "Z"));
    personsById.add(new Person(3, "A"));
    personsById.add(new Person(4, "C"));
    personsById.add(new Person(4, "S")); // A duplicate Person

    System.out.println("Persons by  Id:");
    personsById.forEach(System.out::println);

    SortedSet<Person> personsByName = new TreeSet<>(
        Comparator.comparing(Person::getName));
    personsByName.add(new Person(1, "X"));
    personsByName.add(new Person(2, "Z"));
    personsByName.add(new Person(3, "A"));
    personsByName.add(new Person(4, "C"));

    System.out.println("Persons by  Name: ");
    personsByName.forEach(System.out::println);

  }

}

class Person {
  private int id;
  private String name;

  public Person(int id, String name) {
    this.id = id;
    this.name = name;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof Person)) {
      return false;
    }

    // id must be the same for two Persons to be equal
    Person p = (Person) o;
    if (this.id == p.getId()) {
      return true;
    }

    return false;
  }

  @Override
  public int hashCode() {
    return this.id;
  }

  @Override
  public String toString() {
    return "(" + id + ", " + name + ")";
  }
}

上面的代码生成以下结果。

例3

SortedSet 接口继承了 Set 接口的所有方法,并添加了一些方法来返回子集。

subSet(E fromElement,E toElement)方法从 SortedSet 返回fromElement(包含)和toElement(exclusive)之间的元素。

import java.util.SortedSet;
import java.util.TreeSet;

public class Main {
  public static void main(String[] args) {
    SortedSet<String> names = new TreeSet<>();
    names.add("HTML");
    names.add("Java");
    names.add("SQL");
    names.add("CSS");
    System.out.println("Sorted Set: " + names);
    System.out.println("First: " + names.first());
    System.out.println("Last: " + names.last());

    SortedSet<String> ssBeforeCSS = names.headSet("CSS");
    System.out.println(ssBeforeCSS);

    SortedSet<String> ssBetwenCSSAndHTML = names.subSet("CSS", "HTML");
    System.out.println(ssBetwenCSSAndHTML);

    SortedSet<String> ssBetwenCSSAndHTML2 = names.subSet("CSS", "HTML");
    System.out.println(ssBetwenCSSAndHTML2);

    SortedSet<String> ssCSSAndAfter = names.tailSet("CSS");
    System.out.println(ssCSSAndAfter);

  }

}

上面的代码生成以下结果。

例4

以下代码片段使用 Comparator 创建一个 SortedSet ,它将null元素放在第一位:

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

public class Main {
  public static void main(String[] args) {
    // Sort the names based on their length, placing null first
    SortedSet<String> names = new TreeSet<>(Comparator.nullsFirst(Comparator
        .comparing(String::length)));
    names.add("XML");
    names.add("CSS");
    names.add("HTML");
    names.add(null); // Adds a null

    // Print the names
    names.forEach(System.out::println);

  }

}

上面的代码生成以下结果。

Java 导航集 

Java集合教程 - Java导航集

导航集是一个有序集,允许您使用其子集在各种方式。

NavigableSet 表示Java集合中的可导航集合框架。 NavigableSet 接口继承了SortedSet接口和扩展 SortedSet 

NavigableSet 界面可以以相反的顺序导航集合与SortedSet中定义的顺序相比。

headSet() tailSet() subSet() NavigableSet 接口接受布尔标志以将元素包括在子集边界的开始或结束处。

lower(),floor(),higher()和ceiling()从NavigableSet接口搜索基于搜索条件的元素。

lower()方法返回小于指定元素的最大元素。

floor()方法返回 NavigableSet 中小于或等于指定元素的最大元素。

higher()方法返回最小元素大于指定元素的 NavigableSet 

ceiling()方法返回 NavigableSet 中大于或等于指定元素的最小元素。

pollFirst() pollLast()分别检索和删除 NavigableSet 的第一个和最后一个元素。 如果NavigableSet为空,它们返回null。

TreeSet 类是 NavigableSet 接口的实现类之一。我们可以使用 TreeSet 作为集合,排序集合和可导航集合。

TreeSet APIs

例子

import java.util.NavigableSet;
import java.util.TreeSet;

public class Main {
  public static void main(String[] args) {
    NavigableSet<Integer> ns = new TreeSet<>();
    ns.add(0);
    ns.add(1);
    ns.add(2);
    ns.add(3);
    ns.add(4);
    ns.add(5);
    ns.add(6);

    // Get a reverse view of the navigable set
    NavigableSet<Integer> reverseNs = ns.descendingSet();

    // Print the normal and reverse views
    System.out.println("Normal order: " + ns);
    System.out.println("Reverse order: " + reverseNs);

    NavigableSet<Integer> threeOrMore = ns.tailSet(3, true);
    System.out.println("3 or  more:  " + threeOrMore);
    System.out.println("lower(3): " + ns.lower(3));
    System.out.println("floor(3): " + ns.floor(3));
    System.out.println("higher(3): " + ns.higher(3));
    System.out.println("ceiling(3): " + ns.ceiling(3));

    System.out.println("pollFirst(): " + ns.pollFirst());
    System.out.println("Navigable Set:  " + ns);

    System.out.println("pollLast(): " + ns.pollLast());
    System.out.println("Navigable Set:  " + ns);

    System.out.println("pollFirst(): " + ns.pollFirst());
    System.out.println("Navigable Set:  " + ns);

    System.out.println("pollFirst(): " + ns.pollFirst());
    System.out.println("Navigable Set:  " + ns);

    System.out.println("pollFirst(): " + ns.pollFirst());
    System.out.println("Navigable Set:  " + ns);

    System.out.println("pollFirst(): " + ns.pollFirst());
    System.out.println("pollLast(): " + ns.pollLast());
  }
}

上面的代码生成以下结果。

Java 列表

Java集合教程 - Java列表

列表是对象的有序集合,在 List 界面中定义。 List  接口表示集合框架中的列表。

列表可以具有重复的元素。并且我们可以在列表中存储多个空值。

List 接口继承了集合接口和它添加了一些方法来支持使用索引访问其元素。

我们可以在 List 或的末尾添加一个元素在由整数索引标识的任何位置。

列表中元素的索引是从零开始的。

我们可以使用以下方法使用索引添加,获取,删除和替换其元素。

its add(int index, E  element), 
addAll(int  index, Collection<? extends E> c), 
get(int index), 
remove(int index) 
set(int  index, E  element) 

我们可以搜索元素的位置 List 使用indexOf(Object o)或 lastIndexOf(Object o)方法。

indexOf()方法搜索指定的对象从开始,它返回索引的对象的第一次出现。

lastIndexOf()方法从列表的末尾搜索元素。两个方法都返回-1如果 List 不包含指定的对象。

subList(int fromIndex,int toIndex)返回一个子列表的原始列表从索引fromIndex(包括)到索引toIndex(独占)。

ListIterator  List 接口可以返回在向前和向后方向上遍历其元素。

List APIs

ArrayList和LinkedList

以下是实现 List 接口的两个类:

  • ArrayList
  • LinkedList

ArrayList由数组备份。链接列表由链接列表备份。

如果我们频繁地访问列表的元素,那么 ArrayList 会表现得更好。访问ArrayList中的元素更快,因为它是数组后端。

 ArrayList 添加或删除元素更慢除非从头到尾,因为 ArrayList 必须执行数组副本内部保持元素的顺序。

LinkedList 的性能优于 ArrayList 用于添加和从列表中间删除元素。但是,访问列表中的元素更慢,除非在列表的头部。

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

public class Main {
  public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("Java");
    list.add("Oracle");
    list.add("CSS");
    list.add("XML");

    System.out.println("List: " + list);

    int count = list.size();
    System.out.println("Size of  List: " + count);

    // Print each element with its index
    for (int i = 0; i < count; i++) {
      String element = list.get(i);
      System.out.println("Index=" + i + ", Element=" + element);
    }

    List<String> subList = list.subList(1, 3);
    System.out.println(subList);

    // Remove "CSS" from the list 
    list.remove("CSS"); // Same as list.remove(2);
     System.out.println(list);
  }
}

上面的代码生成以下结果。

ListIterator

我们可以使用 ListIterator 接口以遍历列表。

ListIterator 接口继承了 Iterator 接口并且它增加了几个方法来从当前位置向后访问列表中的元素。

以下代码显示了如何从列表中获取列表迭代器:

ListIterator<String> fullIterator = list.listIterator();

为了得到在正向从索引5开始的列表迭代器,使用以下代码。

ListIterator<String> partialIterator = list.listIterator(5);

以下代码显示如何使用 ListIterator 

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

public class Main {
  public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("Oracle");
    list.add("SQL");
    list.add("CSS");
    list.add("XML");
    System.out.println("List: " + list);
    // Get the list iterator
    ListIterator<String> iterator = list.listIterator();
    while (iterator.hasNext()) {
      int index = iterator.nextIndex();
      String element = iterator.next();
      System.out.println("Index=" + index + ", Element=" + element);
    }
    // Reuse the iterator to iterate from the end to the beginning
    while (iterator.hasPrevious()) {
      int index = iterator.previousIndex();
      String element = iterator.previous();
      System.out.println("Index=" + index + ",  Element=" + element);
    }
  }
}

上面的代码生成以下结果。

ListIterator 可以向前看或回头一个列表。

next()方法向前移动一个索引,而 previous()方法向后移动一个索引。

如果使用 next()方法,后跟 previous()方法,迭代器返回到相同的位置。


http://www.kler.cn/a/376632.html

相关文章:

  • JSON交互处理
  • 长短时记忆网络(LSTM):解决 RNN 长期依赖问题的高手
  • Mybatis学习笔记(二)
  • Pinctrl子系统中Pincontroller构造过程驱动分析:imx_pinctrl_soc_info结构体
  • 服务器上清理Docker容器运行日志的正确方法
  • 中仕公考:上海市25年公务员考试今日报名
  • JAVA 基础-多态
  • 2024年第四届“网鼎杯”网络安全大赛-赛前模拟训练
  • DNS服务部署
  • Java网络通信
  • 从0开始学python-day17-数据结构2
  • layui 实现 城市联动
  • git cherry-pick用法详解
  • 顺序表和链表(一)
  • jmeter结合ansible分布式压测--准备工作
  • 深入了解嵌入式硬件设计
  • 视频智能分析平台LiteAIServer入侵检测算法平台部署行人入侵检测算法:智能安防的新利器
  • 钉钉内集成第三方免密登录(Vue+.Net)
  • 定制化视频生成新模范!零样本主体驱动,精确运动控制!复旦阿里等发布DreamVideo-2
  • 算法笔记day10
  • CentOS下Redis简洁安装(无坑版)
  • LocalDate 类常用方法详解(日期时间类)
  • 图文深入介绍Oracle DB link(三)
  • Python世界:自动化办公Word之批量替换文本生成副本
  • C++ 实现俄罗斯方块游戏
  • 贪心算法习题其二【力扣】【算法学习day.19】