摘记一下最近敲的关于集合方面的Demo,会陆续作成博客记录下来的。算法
此次摘记的是:安全
foreach(T t : Collections c){ ... }
Collections c.forEach(obj-> ...)
Iterator
对象进行遍历Set
接口的四种常见实现类:
这里补充说明下,上述的四种Set都是非线程安全的,即须要使用代码同步机制保证多线程访问的安全性。想使用线程安全的Set,可采用_synchronizedSortedSet_(线程安全)。数据结构
如下为笔者学习时采用的Demo,笔者将一些心得记录放在了Demo的注释中,若是有dalao能够指点下小弟,欢迎私信:xb1997love@gmail.com多线程
public class SetDemo { static SetDemo mine = new SetDemo(); /** * 这是通常的Lambda表达式遍历集合 */ public void LambdaEx() { Collection<Integer> i = new HashSet<Integer>(); i.add(1); i.add(2); i.add(3); i.add(4); i.forEach(obj -> System.out.println(obj)); } /** * 这是Lambda遍历Iterator对象 */ public void LambdaIterator() { Collection<Integer> i = new HashSet<Integer>(); i.add(1); i.add(2); i.add(3); i.add(4); Iterator<Integer> it = i.iterator(); // 这是传统的使用Iterator对象循环遍历集合 // while(it.hasNext()) { // int num = (Integer)it.next(); // if(num == 3) { // it.remove(); // } // System.out.println(num); // } // 利用Lambda表达式循环输出对象 it.forEachRemaining(obj -> System.out.println(obj)); } /** * 这个是用来显示Java 8中的IntStream LongStream DoubleStream等流式接口 */ public void IntLongDoubleStream() { IntStream is = IntStream.builder().add(1).add(13).add(20).add(18).build(); Collection<Integer> c = new HashSet<Integer>(); c.add(1); c.add(2); c.add(3); c.add(4); // // 下面的汇集方法的代码每次只能被调用一,就是下面的max() min() 等只能同时调用一个 // System.out.println("MAX: "+ is.max().getAsInt()); // System.out.println("MIN: "+is.min().getAsInt()); // // 这个是用于匹配is中的全部元素是否都知足所述的要求 // System.out.println("is 中全部元素的平方是否大于20:"+is.allMatch(ele->ele*ele>20)); // // 这是对is中全部的对象进行修改 // IntStream newIs = is.map(ele->ele*2); // newIs.forEach(ele->System.out.println(ele)); c.stream().filter(ele -> ele > 4); } /** * TreeSet Demo代码 TreeSet * 会自动对插入的元素进行排序,假若数据是使用的自定义的类型,那么那个类型须要实现Comparable接口(compareTo方法) TreeSet * 实际上应该是一颗彻底二叉树,而且对插入的数据进行修改的话可能会致使Set混乱,由于会出现无序而且没法找到元素的状况 * 读出数据的时候会采用中序遍历的方式进行读出 */ public void TreeSetDemo() { // 默认的,使用基本的数字类型的会按照递增的顺序排列 TreeSet<M> tSet = new TreeSet<M>((o1, o2) -> { M m1 = (M) o1; M m2 = (M) o2; // 递减的排序 return m1.age > m2.age ? -1 : m1.age < m2.age ? 1 : 0; }); // 插入三条数据 tSet.add(new M(5)); tSet.add(new M(-3)); tSet.add(new M(9)); System.out.println(tSet); } /** * HashSet Demo代码 * HashSet保存元素是无序且惟一的,若是企图修改其中的元素会致使Set进入混乱的状态,进而Set没法识别对应的元素,没法精肯定位元素 * 假若须要重写equals方法切近最后也重写hashCode方法,由于equals方法相等的对象,它们的hashCode也应该相同。而HashSet须要利用这两个函数进行重复的判断 */ public void HashSetDemo() { Set<R> hSet = new HashSet<R>(); hSet.add(new R(5)); hSet.add(new R(-3)); hSet.add(new R(9)); hSet.add(new R(-2)); hSet.add(new R(3)); // 初始状态hSet System.out.println(hSet); // 这里能够给所引发加上一个type Iterator<R> it = hSet.iterator(); // 作了一个很危险的操做,将Set的第一个元素的值修改成-3 R first = (R) it.next(); first.count = -3; // 修改后状态hSet System.out.println(hSet); System.out.println("hSet 是否包含-2的元素? " + hSet.contains(new R(-2))); // 试图移除这个R(-3)对象 hSet.remove(new R(-3)); System.out.println(hSet); System.out.println("hSet 是否包含-3的元素? " + hSet.contains(new R(-3))); System.out.println("hSet 是否包含-2的元素? " + hSet.contains(new R(-2))); } /** * LinkedHashSet相较于HashSet的不一样是,LinkedHashSet会以链表的形式维护插入元素的顺序 */ public void LinkedHashSetDemo() { Set<String> lSet = new LinkedHashSet<String>(); // 重点是观察其插入是具备有序性的,即LinkedHashSet会维持元素插入的顺序 lSet.add("t1"); lSet.add("t2"); System.out.println(lSet); // 移除再从新插入,顺序会改变 lSet.remove("t1"); lSet.add("t1"); System.out.println(lSet); } /** * EnumSet Demo代码 EnumSet 采用的是位向量来存储变量,进行批量操做(ContainsAll retainAll()方法)特别合适 * EnumSet 不容许插入null值 */ public void EnumSetDemo() { // 以一个枚举类型建立一个EnumSet,此时会以枚举的全部值填充此EnumSet EnumSet<Season> eSet = EnumSet.allOf(Season.class); // 以一个枚举类型建立一个空的EnumSet,这里只是单纯地指定了枚举的类型 EnumSet<Season> eSet2 = EnumSet.noneOf(Season.class); // 比较下两种EnumSet的区别 System.out.println(eSet); System.out.println(eSet2); // 试图插入一个枚举值 eSet2.add(Season.SPRING); // 以指定的枚举值建立EnumSet EnumSet<Season> eSet3 = EnumSet.of(Season.SPRING,Season.SUMMER); // 以枚举类型中指定范围的值建立EnumSet EnumSet<Season> eSet4 = EnumSet.range(Season.SPRING,Season.WINTER); // eSet5 + eSet4 -> Season中全部的枚举值 EnumSet<Season> eSet5 = EnumSet.complementOf(eSet4); } public static void main(String[] args) { // TODO Auto-generated method stub // Lambda遍历集合的方式 // mine.LambdaIterator(); // 使用Stream对象遍历集合的方式 // mine.IntLongDoubleStream(); // 常见的三种Set接口实现类 // mine.TreeSetDemo(); // mine.HashSetDemo(); // mine.LinkedHashSetDemo(); // mine.EnumSetDemo(); } /** * 用于演示TreeSet的类,该类未实现Comparable接口,而是将比较的方式在构建TreeSet的时候以构造函数的形式注入了 * * @author Administrator * */ class M { int age = 0; public M(int age) { this.age = age; } public String toString() { return String.format("M[ age: %d]", age); } } /** * 用于演示HashSet的类,关键在于重写equals和hashCode方法 * @author Administrator * */ class R { int count; public R(int count) { this.count = count; } @Override public String toString() { // TODO Auto-generated method stub return String.format("R[count:%d]", count); } @Override public boolean equals(Object obj) { // TODO Auto-generated method stub if (this == obj) { return true; } if (obj != null && obj.getClass() == R.class) { R r = (R) obj; return this.count == r.count; } return false; } @Override public int hashCode() { // TODO Auto-generated method stub return this.count; // return super.hashCode(); } } /** * 用于演示EnumSet的类 * @author Administrator * */ enum Season{ SPRING,SUMMER,FAIL,WINTER } }