2021-04-18 11:19  阅读(99)
文章分类:Java 基础教程 文章标签:JavaJava 教程
©  原文作者:w3cschool 原文地址:https://www.w3cschool.cn/java/java-collections-traversing.html

Java集合教程 - Java集合算法

列表排序

Collection类中的两个静态方法会对List进行排序。

  • sort(List list)按照由元素实现的Comparable接口定义的顺序对List中的元素进行排序。

  • sort(List list,Comparator c)使用传入的Comparator对象对元素进行排序。

我们还可以使用List接口中的sort(Comparator c)对List进行排序,而不使用Collections类。

以下代码演示了如何对List进行排序:

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("J");
        list.add("R");
        list.add("C");
        list.add("X");
    
        System.out.println("List: " + list);
    
        // Uses Comparable implementation in String class
        // to sort the list in natural order
        Collections.sort(list);
        System.out.println("Sorted List:  " + list);
    
      }
    }
    

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

2021041811111112_1.png

例子

以下代码使用List接口中的sort()方法按其元素长度的升序对列表进行排序:

    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("R");
        list.add("CSS");
        list.add("XML");
    
        System.out.println("List: " + list);
    
        // Uses List.sort() method with a Comparator
        list.sort(Comparator.comparing(String::length));
    
        System.out.println("Sorted List:  " + list);
    
      }
    }
    

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

20210418111113_2.png

sort()方法使用修改的mergeesort算法,这是一个稳定的排序。

在稳定的排序中,相等的元素将在排序操作之后保持在它们当前的位置。

排序提供了n*log(n)性能,其中n是列表中元素的数量。

搜索列表

Collections类中的两个静态binarySearch()方法在List中搜索键。

该方法使用二分搜索算法执行搜索。

    int  binarySearch(List list,  T  key)
    int  binarySearch(List list, T  key, Comparator c)
    

List必须按升序排序,然后才能使用binarySearch()方法。

如果在列表中找到该键,则该方法将在列表中返回其索引。

如果在列表中没有找到键,它返回( - (insertion_index)-1),其中Math.abs(( - (insertion_index)-1))是我们可以插入这个键的索引仍然保持列表订购。

在列表中找不到键时,返回值为负值。

以下代码段显示了如何使用此方法:

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("R");
        list.add("CSS");
        list.add("XML");
    
        Collections.sort(list);
        System.out.println("List: " + list);
    
        int index = Collections.binarySearch(list, "CSS");
        System.out.println("CSS in List  is at " + index);
    
        index = Collections.binarySearch(list, "Javascript");
        System.out.println("Javascript in List is  at " + index);
    
      }
    }
    

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

2021041811115_3.png

由于“Javascript”不在列表中,二进制搜索返回-3。这意味着如果在列表中插入“Javascript”,它将被插入索引2,使用表达式( - ( - 2 + 1))计算。

随机播放列表

Shuffle给我们一个列表中的元素的随机排列。

来自Collections类的shuffle()方法的两个版本如下:

    void  shuffle(List list)
    void  shuffle(List list, Random  rnd)
    
    

以下代码显示如何使用shuffle方法。

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("R");
        list.add("CSS");
        list.add("XML");
    
        Collections.sort(list);
        System.out.println("List: " + list);
    
        Collections.shuffle(list);
        System.out.println("List: " + list);
    
        Collections.shuffle(list);
        System.out.println("List: " + list);
      }
    }
    

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

2021041811113_4.png

反向列表

我们可以使用Collections类的reverse()的静态方法来反转列表中的元素。

    void  reverse(List list)
    

以下代码显示如何使用reverse()方法。

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("R");
        list.add("CSS");
        list.add("XML");
    
        Collections.sort(list);
        System.out.println("List: " + list);
    
        Collections.reverse(list);
        System.out.println("List: " + list);
    
      }
    }
    

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

2021041811110_5.png

交换列表项

交换交换列表中的两个元素。

Collections类的swap()静态方法执行交换。

    void  swap(List list, int i, int j)
    

ij是两个元素的索引,它们必须在0和size-1之间,其中size是List的大小。

以下代码显示了如何使用这些方法对List的元素重新排序。

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("R");
        list.add("CSS");
        list.add("XML");
    
        Collections.sort(list);
        System.out.println("List: " + list);
    
        // Swap elements at indexes 1 and 3
        Collections.swap(list, 1, 3);
        System.out.println(list);
    
      }
    }
    

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

202104181119_6.png

旋转列表

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("R");
        list.add("CSS");
        list.add("XML");
    
        Collections.sort(list);
        System.out.println("List: " + list);
    
        // Rotate elements by 2
        Collections.rotate(list, 2);
        System.out.println("After  Rotating by  2: " + list);
    
      }
    }
    

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

202104181119_7.png

创建集合的不同视图

我们可以使用Collections类的asLifoQueue()静态方法创建Deque的LIFO队列视图:

    <T> Queue<T> asLifoQueue(Deque<T>  deque)
    

要将Map的实现用作Set实现,请使用Collections类的newSetFromMap()静态方法:

    <E> Set<E> newSetFromMap(Map<E, Boolean>  map)
    

只读集合视图

当将集合传递到其他方法时,我们可以获取集合的只读视图,并且我们不希望被调用的方法修改集合。

Collections类提供了以下方法来获取不同类型集合的只读视图:

    <T> Collection<T> unmodifiableCollection(Collection<?  extends T> c)
    <T> List<T>  unmodifiableList(List<?  extends T> list)
    <K,V> Map<K,V>  unmodifiableMap(Map<?  extends K,?  extends V>  m)
    <K,V> NavigableMap<K,V> unmodifiableNavigableMap(NavigableMap<K,? extends  V>  m)
    <T> Set<T> unmodifiableSet(Set<? extends T> s)
    <T> NavigableSet<T> unmodifiableNavigableSet(NavigableSet<T>  s)
    static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T>  s)
    <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends  V>  m)
    

我们传递一个特定类型的集合,并获得相同类型的只读集合。

集合的同步视图

我们可以使用Collections类的以下静态方法之一获取集合的同步视图。

    <T> Collection<T> synchronizedCollection(Collection<T>  c)
    <T> List<T>  synchronizedList(List<T> list)
    <K,V> Map<K,V>  synchronizedMap(Map<K,V> m)
    <K,V> NavigableMap<K,V> synchronizedNavigableMap(NavigableMap<K,V> m)
    <T> NavigableSet<T> synchronizedNavigableSet(NavigableSet<T>  s)
    <T> Set<T> synchronizedSet(Set<T> s)
    <T> SortedSet<T> synchronizedSortedSet(SortedSet<T>  s)
    <K,V> SortedMap<K,V> synchronizedSortedMap (SortedMap<K,V> m)
    

检查集合

泛型为集合提供编译时类型安全。

下面的代码有一个编译时错误,因为我们试图添加Integer类型值到一个只能有String值的Set。

    Set<String> s = new HashSet<>();
    s.add("Hello");
    a.add(new Integer(1)); // A compile-time error
    

我们可以通过使用以下代码绕过编译器检查:

    Set<String> s = new HashSet<  >();
    s.add("Hello");
    
    Set s2 = s;
    s2.add(new Integer(123)); // No  runtime exception
    

我们可以通过使用检查的集合避免上述错误。Collection类的以下静态方法返回特定类型的已检查集合:

    <E> Collection<E> checkedCollection(Collection<E>  c, Class<E>  type)
    <E> List<E>  checkedList(List<E> list, Class<E>  type)
    <K,V> Map<K,V> checkedMap(Map<K,V>   m, Class<K> keyType,  Class<V> valueType)
    <K,V> NavigableMap<K,V> checkedNavigableMap(NavigableMap<K,V>  m, Class<K> keyType,  Class<V> valueType)
    <E> NavigableSet<E> checkedNavigableSet(NavigableSet<E>  s, Class<E>  type)
    <E> Queue<E> checkedQueue(Queue<E> queue, Class<E>  type)
    <E> Set<E> checkedSet(Set<E> s, Class<E>  type)
    <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K,V>  m, Class<K> keyType, Class<V> valueType)
    <E> SortedSet<E> checkedSortedSet(SortedSet<E>  s, Class<E>  type)
    

下面的代码重写了上面的代码。

    Set<String>  checkedSet = Collections.checkedSet(new HashSet<String>(),  String.class);
    Set s2 = checkedSet;
    s2.add(new Integer(1)); // Throws ClassCastException
    

创建空集合

Collections类可以返回每种类型的不可变空集合对象。

它也可以返回一个空的迭代器。以下代码在Collections类中列出了这些静态方法:

    <T> List<T>  emptyList()
    <K,V> Map<K,V>  emptyMap()
    <T> Set<T> emptySet()
    <T> Iterator<T> emptyIterator()
    <T> ListIterator<T> emptyListIterator()
    

Singleton集合

我们可以使用Collections类创建一个只有一个元素的集合。

我们必须创建这种集合对象,当一个方法接受一个集合作为其参数,我们只有一个对象传递给该方法。

这些方法如下:

    <T> Set<T> singleton(T o)
    <T> List<T>  singletonList(T o)
    <K,V> Map<K,V>  singletonMap(K key,  V  value)
    

以下代码显示了如何使用Collections.singleton()方法。

    Set<String> singletonSet  = Collections.singleton("Lonely");
    // Throws a  runtime exception since a singleton set is immutable singletonSet.add("Hello");
    
点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Java 集合算法
上一篇
Java 特殊类型映射
下一篇
Java 正则表达式元字符