前言:
当前看官们对“java不可重复集合”大概比较关注,兄弟们都想要了解一些“java不可重复集合”的相关知识。那么小编同时在网络上收集了一些对于“java不可重复集合””的相关内容,希望看官们能喜欢,姐妹们一起来学习一下吧!集合:集合与数组一样,可以保存一组元素,并且提供了操作元素的相关方法,使用更方便.
Collection接口:单列数据,定义了存取一组对象的方法的集合
List:元素有序(指的是存储时,与存放顺序保持一致)、可重复的集合Set:元素无序、不可重复的集合
ArrayList和LinkedList的异同?
答:二者都线程不安全,相对线程安全的Vector,执行效率高。此外,ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。对于新增和删除操作add(特指插入)和remove,LinkedList比较占优势,因为ArrayList要移动数据。
ArrayList和Vector的区别?
Vector和ArrayList几乎是完全相同的,唯一的区别在于Vector是同步类(synchronized),属于强同步类。因此开销就比ArrayList要大,访问要慢。正常情况下,大多数的Java程序员使用ArrayList而不是Vector,因为同步完全可以由程序员自己来控制。Vector每次扩容请求其大小的2倍空间,而ArrayList是1.5倍。Vector还有一个子类Stack。
java.util.Collection接口:
java.util.Collection是所有集合的顶级接口.Collection下面有多种实现类,因此我们有更多的数据结构可供选择.
Collection下面有两个常见的子接口:
- java.util.List:线性表.是可重复集合,并且有序.- java.util.Set:不可重复的集合,大部分实现类是无序的.
这里可重复指的是集合中的元素是否可以重复,而判定重复元素的标准是依靠元素自身equals比较的结果.为true就认为是重复元素.
Collection c = new ArrayList(); /* boolean add(E e) 向当前集合中添加一个元素.当元素成功添加后返回true */ c.add("one"); c.add("two"); c.add("three"); c.add("four"); c.add("five"); System.out.println(c); /* int size() 返回当前集合的元素个数 */ int size = c.size(); System.out.println("size:"+size); /* boolean isEmpty() 判断当前集合是否为空集(不含有任何元素) */ boolean isEmpty = c.isEmpty(); System.out.println("是否为空集:"+isEmpty); /* 清空集合 */ c.clear(); System.out.println(c); System.out.println("size:"+c.size());//0 System.out.println("是否为空集:"+c.isEmpty());
集合:取并集,删交集,判断包含子集等操作
Collection c1 = new HashSet();//不可重复元素 c1.add("java"); c1.add("c"); c1.add("c++"); System.out.println("c1:"+c1); Collection c2 = new ArrayList(); c2.add("android"); c2.add("ios"); c2.add("java"); System.out.println("c2:"+c2); /* boolean addAll(Collection c) 将给定集合中的所有元素添加到当前集合中。当前集合若发生了改变则返回true */ boolean tf = c1.addAll(c2); System.out.println(tf); System.out.println("c1:"+c1); System.out.println("c2:"+c2); Collection c3 = new ArrayList(); c3.add("ios"); c3.add("c++"); c3.add("php"); System.out.println("c3:"+c3); /* boolean containsAll(Collection c) 判断当前集合是否包含给定集合中的所有元素 */ boolean contains = c1.containsAll(c3); System.out.println("包含所有元素:"+contains); /* boolean removeAll(Collection c) 删除当前集合中与给定集合中的共有元素 */ c1.removeAll(c3); System.out.println("c1:"+c1); System.out.println("c3:"+c3);
Collection子接口:Set接口
Set接口是Collection的子接口,set接口没有提供额外的方法。Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set 集合中,则添加操作失败。Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法
Set实现类之一:HashSet
HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。HashSet 具有以下特点:不能保证元素的排列顺序、HashSet 不是线程安全的、集合元素可以是 nullHashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。
Set实现类之二:LinkedHashSet
LinkedHashSet 是 HashSet 的子类LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的。LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。LinkedHashSet 不允许集合元素重复。
Set实现类之三:TreeSet
TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。TreeSet底层使用红黑树结构存储数据TreeSet 两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。
集合的遍历 Collection提供了统一的遍历集合方式:迭代器模式 Iterator iterator()
java.util.Iterator接口
迭代器接口,定义了迭代器遍历集合的相关操作.
不同的集合都实现了一个用于遍历自身元素的迭代器实现类,我们无需记住它们的名字,用多态的角度把他们看做为Iterator即可.
迭代器遍历集合遵循的步骤为:问,取,删.其中删除元素不是必要操作
Collection c = new ArrayList(); c.add("one"); c.add("two"); c.add("three"); c.add("four"); c.add("five"); System.out.println(c); //获取迭代器 Iterator it = c.iterator(); /* 迭代器提供的相关方法: boolean hasNext() 判断集合是否还有元素可以遍历 E next() 获取集合下一个元素(第一次调用时就是获取第一个元素,以此类推) */ while(it.hasNext()){ String str = (String)it.next(); System.out.println(str); } System.out.println(c);
迭代器遍历过程中不得通过集合的方法增删元素
/** * Collection接口没有定义单独获取某一个元素的操作,因为不通用。 * 但是Collection提供了遍历集合元素的操作。该操作是一个通用操作,无论什么类型的 * 集合都支持此种遍历方式:迭代器模式。 * * Iterator iterator() die(二声) * 该方法会获取一个用于遍历当前集合元素的迭代器 * * java.util.Iterator接口,是迭代器接口,规定了迭代器遍历集合的相关操作,不同的 * 集合都提供了一个用于遍历自身元素的迭代器实现类,不过我们不需要直到它们的名字,以 * 多态的方式当成Iterator使用即可。 * 迭代器遍历集合遵循的步骤为:问->取->删 * 其中删除不是必须操作。 */Collection c = new ArrayList(); c.add("one"); c.add("#"); c.add("two"); c.add("#"); c.add("three"); c.add("#"); c.add("four"); c.add("#"); c.add("five"); System.out.println(c); //获取迭代器 Iterator it = c.iterator(); /* 迭代器提供的相关方法: boolean hasNext() 判断集合是否还有元素可以遍历 E next() 获取集合下一个元素(第一次调用时就是获取第一个元素,以此类推) */ while(it.hasNext()){ String str = (String)it.next(); System.out.println(str); if("#".equals(str)){ /* 迭代器要求遍历的过程中不得通过集合的方法增删元素 否则会抛出异常:ConcurrentModificationException */// c.remove(str); /* 迭代器的remove方法可以将通过next方法获取的元素从集合 中删除。 */ it.remove(); } } System.out.println(c);
增强型for循环
JDK5之后推出了一个特性:增强型for循环 - 也称为新循环,使得我们可以使用相同的语法遍历集合或数组.
//语法:// for(元素类型 变量名 : 集合或数组){// 循环体// }Collection c = new ArrayList(); c.add("one"); c.add("two"); c.add("three"); c.add("four"); c.add("five"); //迭代器遍历 Iterator it = c.iterator(); while(it.hasNext()){ String str = (String)it.next(); System.out.println(str); } //新循环遍历 for(Object o : c){ String str = (String)o; System.out.println(str); }
泛型 JDK5之后 泛型也称为参数化类型,允许我们在使用一个类时指定它当中属性,方法参数或返回值的类型.
- 泛型在集合中被广泛使用,用来指定集合中的元素类型.- 有泛型支持的类在使用时若不指定泛型的具体类型则默认为原型Object
public static void main(String[] args) { String[] array = {"one","two","three","four","five"}; for(int i=0;i<array.length;i++){ String str = array[i]; System.out.println(str); } for(String str : array){ System.out.println(str); } /* * 泛型 JDK5之后推出的另一个特性。 * 泛型也称为参数化类型,允许我们在使用一个类时指定它里面属性的类型, * 方法参数或返回值的类型,使得我们使用一个类时可以更灵活。 * 泛型被广泛应用于集合中,用来指定集合中的元素类型。 * 支持泛型的类在使用时如果未指定泛型,那么默认就是原型Object * * Collection接口的定义 * public interface Collection<E> ... { * * Collection<E> 这里的<E>就是泛型 * * Collection中add方法的定义,参数为E * boolean add(E e) */ Collection<String> c = new ArrayList<>(); c.add("one");//编译器会检查add方法的实参是否为String类型 c.add("two"); c.add("three"); c.add("four"); c.add("five");// c.add(123);//编译不通过 //迭代器遍历 //迭代器也支持泛型,指定的与其遍历的集合指定的泛型一致即可 Iterator<String> it = c.iterator(); while(it.hasNext()){ //编译器编译代码时会根据迭代器指定的泛型补充造型代码 String str = it.next();//获取元素时无需在造型 System.out.println(str); } //新循环遍历 for(String str : c){ System.out.println(str); } }
List集 java.util.List接口,继承自Collection.
List集合是可重复集,并且有序,提供了一套可以通过下标操作元素的方法
- java.util.ArrayList:内部使用数组实现,查询性能更好.- java.util.LinkedList:内部使用链表实现,首尾增删元素性能更好.
List<String> list = new ArrayList<>();// List<String> list = new LinkedList<>(); list.add("one"); list.add("two"); list.add("three"); list.add("four"); list.add("five"); /* E get(int index) 获取指定下标对应的元素 */ //获取第三个元素 String e = list.get(2); System.out.println(e); for(int i=0;i<list.size();i++){ e = list.get(i); System.out.println(e); } /* E set(int index,E e) 将给定元素设置到指定位置,返回值为该位置原有的元素。 替换元素操作 */ //[one,six,three,four,five] String old = list.set(1,"six"); System.out.println(list); System.out.println("被替换的元素是:"+old); /* E remove(int index) 删除并返回指定位置上的元素 */ //[one,six,three,four,five] String e = list.remove(1); System.out.println(list); System.out.println("被删除的元素:"+e);
subList()方法
List<Integer> list = new ArrayList<>();for(int i=0;i<10;i++){ list.add(i); }System.out.println(list);//获取3-7这部分List<Integer> subList = list.subList(3,8);System.out.println(subList);//将子集每个元素扩大10倍for(int i=0;i<subList.size();i++){subList.set(i,subList.get(i) * 10); }//[30,40,50,60,70]System.out.println(subList); /* 对子集元素的操作就是对原集合对应元素的操作 */System.out.println(list);//删除list集合中的2-8list.subList(2,9).clear();System.out.println(list);
集合与数组的转换
List<String> list = new ArrayList<>(); list.add("one"); list.add("two"); list.add("three"); list.add("four"); list.add("five"); System.out.println(list);// Object[] array = list.toArray();/* 重载的toArray方法要求传入一个数组,内部会将集合所有元素存入该数组 后将其返回(前提是该数组长度>=集合的size)。如果给定的数组长度不足, 则方法内部会自行根据给定数组类型创建一个与集合size一致长度的数组并 将集合元素存入后返回。 */ String[] array = list.toArray(new String[list.size()]); System.out.println(array.length); System.out.println(Arrays.toString(array));
数组转换为List集合
String[] array = {"one","two","three","four","five"}; System.out.println(Arrays.toString(array)); List<String> list = Arrays.asList(array); System.out.println(list); list.set(1,"six"); System.out.println(list); //数组跟着改变了。注意:对数组转换的集合进行元素操作就是对原数组对应的操作 System.out.println(Arrays.toString(array)); /* 由于数组是定长的,因此对该集合进行增删元素的操作是不支持的,会抛出 异常:java.lang.UnsupportedOperationException */// list.add("seven"); /* 若希望对集合进行增删操作,则需要自行创建一个集合,然后将该集合元素 导入。 */// List<String> list2 = new ArrayList<>();// list2.addAll(list); /* 所有的集合都支持一个参数为Collection的构造方法,作用是在创建当前 集合的同时包含给定集合中的所有元素 */ List<String> list2 = new ArrayList<>(list); System.out.println("list2:"+list2); list2.add("seven"); System.out.println("list2:"+list2);
集合的排序
java.util.Collections类
Collections是集合的工具类,里面定义了很多静态方法用于操作集合.
Collections.sort(List list)方法 可以对List集合进行自然排序(从小到大)
List<Point> list = new ArrayList<>();list.add(new Point(1,2));list.add(new Point(97,88));list.add(new Point(7,6));list.add(new Point(9,9));list.add(new Point(5,4));list.add(new Point(2,3));System.out.println(list);/* 编译不通过的原因: Collections.sort(List list)该方法要求集合中的元素类型必须实现接口: Comparable,该接口中有一个抽象方法compareTo,这个方法用来定义元素之间比较 大小的规则.所以只有实现了该接口的元素才能利用这个方法比较出大小进而实现排序 操作. */Collections.sort(list);//编译不通过 compare比较 comparable可以比较的System.out.println(list);
【注】实际开发中,我们并不会让我们自己定义的类(如果该类作为集合元素使用)去实现Comparable接口,因为这对我们的程序有**侵入性**.
侵入性:当我们调用某个API功能时,其要求我们为其修改其他额外的代码,这个现象就是侵入性.侵入性越强的API越不利于程序的后期可维护性.应当尽量避免.
//------------解决侵入性---重载的Collections.sort(List list,Comparator c)方法-----//匿名内部类的形式创建一个比较器Comparator<Point> com = new Comparator<Point>() { @Override /* * 实现比较器接口后必须重写方法compare. * 该方法用来定义参数o1与参数o2的比较大小规则 * 返回值用来表示o1与o2的大小关系 */ public int compare(Point o1, Point o2) { int len1 = o1.getX() * o1.getX() + o1.getY() * o1.getY(); int len2 = o2.getX() * o2.getX() + o2.getY() * o2.getY(); return len1-len2; }};Collections.sort(list,com);//回调模式
排序没有侵入性写法
List<Point> list = new ArrayList<>(); list.add(new Point(1,2)); list.add(new Point(97,88)); list.add(new Point(7,6)); list.add(new Point(9,9)); list.add(new Point(5,4)); list.add(new Point(2,3)); System.out.println(list);//匿名内部类的形式创建一个比较器// Comparator<Point> com = new Comparator<Point>() {// @Override// /**// * 实现比较器接口后必须重写方法compare.// * 该方法用来定义参数o1与参数o2的比较大小规则// * 返回值用来表示o1与o2的大小关系// */// public int compare(Point o1, Point o2) {// int len1 = o1.getX() * o1.getX() + o1.getY() * o1.getY();// int len2 = o2.getX() * o2.getX() + o2.getY() * o2.getY();// return len1-len2;// }// };// Collections.sort(list,com);//回调模式// Collections.sort(list,new Comparator<Point>() {// public int compare(Point o1, Point o2) {// int len1 = o1.getX() * o1.getX() + o1.getY() * o1.getY();// int len2 = o2.getX() * o2.getX() + o2.getY() * o2.getY();// return len1-len2;// }// }); // 没有侵入的 Lambda表达式 写法 Collections.sort(list,(o1,o2)-> o1.getX() * o1.getX() + o1.getY() * o1.getY() - o2.getX() * o2.getX() - o2.getY() * o2.getY() ); System.out.println(list);
学习记录,如有侵权请联系删除
标签: #java不可重复集合