
本文共 9043 字,大约阅读时间需要 30 分钟。
0x01、集合概念
先来了解一些什么是集合,
下面来贴一段集合的描述。集合:java中的一种容器,可以用来存储多个数据。
在这里要理清楚的一个概念,数组的长度是固定的,一旦定义了就无法改名,而集合是可以改变的。
集合存储的都是对象,对象的类型可以不一样,但是数组只能存储基本数据类型。
集合架构
集合按照存储的结构可以分为两类,分别是单列集合(java.util.Collection)和双列集合(java.util.Map),这里就先来讲讲collection集合。
collection是单列集合类的根接口,用于存储符合某种规则的元素,他有两个主要的子接口,分别是java.util.List
和java.util.Set
。
来说说这两个子接口的区别,List的特点是存储的元素有序,元素可以重复。而set的特点是元素无序、存储的元素不可重复。List的接口主要实现类有ArrayList 和LinkedList,Set接口的主要实现类有HashSet和TreeSet
0x02、Collection
Collection是所有单列集合的父接口,也就是说collection是所有单列集合的最顶层的。因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。
* `public boolean add(E e)`: 把给定的对象添加到当前集合中 。* `public void clear()` :清空集合中所有的元素。* `public boolean remove(E e)`: 把给定的对象在当前集合中删除。* `public boolean contains(E e)`: 判断当前集合中是否包含给定的对象。* `public boolean isEmpty()`: 判断当前集合是否为空。* `public int size()`: 返回集合中元素的个数。* `public Object[] toArray()`: 把集合中的元素,存储到数组中。
这里使用一下这几个方法
public class Input { public static void main(String[] args) { Collectionlist = new ArrayList<>(); list.add("123"); list.add("321"); list.remove("123"); boolean a = list.isEmpty(); System.out.println(a); System.out.println(list); }}
1、迭代器
在我们想要遍历的时候,通常都会用到for循环。但是这里遍历集合,java给我们提供了Iterator接口,也就是迭代器,该接口也是集合的一种。
首先来了解迭代的概念:
Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
常用方法:
public E next():返回迭代的下一个元素。public boolean hasNext():如果仍有元素可以迭代,则返回 true。
代码实例:
public static void main(String[] args) { Collectionlist = new ArrayList<>(); list.add("123"); list.add("321"); list.add("baidu"); list.add("google"); Iterator is = list.iterator(); while (is.hasNext()){ String i = is.next(); System.out.println(i); } }
这里使用while循环的条件是判断集里面是否有值,然后再读取值赋值给i。代码的整体还是比较简单的。
2、增强for循环
增强for循环是我们在遍历集合里面,用的最多的,语法简单。他的他的内部原理其实也是个Iterator迭代器。
格式:
for(元素的数据类型 变量 : Collection集合or数组){ ...}
通常只进行遍历元素,增强for里面不能做增删的操作。
public static void main(String[] args) { Collectionlist = new ArrayList<>(); list.add("123"); list.add("321"); list.add("baidu"); list.add("google"); for (String s : list) { System.out.println(s); } }
在使用IDEA编写的时候普遍会有提示。
3、泛型
泛型是一种未知的数据类型,如果我们不知道什么数据类型的时候就可以使用泛型。
代码格式:
修饰符 class 类名<代表泛型的变量> { }
含有泛型的类:
public class Demo11{ private R r; public R getR() { return r; } public void setR(R r) { this.r = r; }}main方法代码:public class DemoMain { public static void main(String[] args) { Demo11 str = new Demo11<>(); str.setR("123"); System.out.println(str.getR()); }}
含有泛型的方法:
类: publicvoid method(R r){ System.out.println(r); }}main方法代码: public static void main(String[] args) { Demo11 abc = new Demo11(); abc.method("abc"); }
调用方法时,确定泛型的类型
含有泛型的接口:
代码实例:
定义格式:
修饰符 interface接口名<代表泛型的变量> { }
public interface MyInterface{ public abstract void add(R r); public abstract R getR();}实现接口类:public class MyInterfaceimpl implements MyInterface { @Override public void add(String s) { System.out.println(s); } @Override public String getR() { return null; }}
这里是在实现接口里面,确定泛型类型。
如果说始终无法确定类型,也可以在创建对象的时候来确定该类型。
实现类:public class MyInterfaceimplimplements MyInterface { @Override public void add(R r) { System.out.println(r); } @Override public R getR() { return null; }}main方法代码: public static void main(String[] args) { MyInterfaceimpl str = new MyInterfaceimpl<>(); str.add("123"); }
在创建对象的时候,确定了类型为string类型。
4、List 接口
List接口是Collection的子接口,
List接口里面允许出现重复元素得,在程序中可以通过索引来访问。List接口存储的数据是有序的。public class DemoMain { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add("狗子"); list.add("二狗"); list.add("狗蛋"); list.add(1,"狗蛋子"); list.remove(1); System.out.println(list); }}
5、set接口
set接口也是继承了Collection接口,也是单列集合。
set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。set接口的实现类有:
AbstractList、 AbstractSequentialList、 ArrayList, AttributeList、 CopyOnWriteArrayList、 LinkedList, RoleList、 RoleUnresolvedList、Stack、 Vector。
Hashset
Hashset所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致)。
这就来用hashset这个实现类来演示public static void main(String[] args) { HashSetlist = new HashSet<>(); list.add("123"); list.add("785"); list.add(new String("23")); for (String s : list) { System.out.println(s); } }
LinkHashSet
hashset是为了保证元素唯一性,如果想要有序这时候就需要用到LinkedHashSet。
public static void main(String[] args) { Setset = new LinkedHashSet<>(); set.add("123"); set.add("12"); set.add("12999"); set.add("1453"); set.add("543"); for (String s : set) { System.out.println(s); } }
可变参数
这里来穿插一点关于可变参数的小知识点。
如果我们定义一个方法需要接受多个参数,并且多个参数类型一致。
定义格式:
修饰符 返回值类型 方法名(参数类型... 形参名){ }
public static void main(String[] args) { int[] arr = {1,2,3,4}; method(1,1,1,1);//使用可变参数方法 method1(arr);//不使用可变参数方法 } private static void method1(int[] args) { for (int arg : args) { System.out.println(arg); } } private static void method(int... args) { System.out.println(args); }
这里可以看到2种定义方式,一个是使用了可变参数的方式,这里就可以直接省去先定义一个数组再对其传入的麻烦。
注意:如果在方法书写时,这个方法拥有多参数,参数中包含可变参数,可变参数一定要写在参数列表的末尾位置。
0x03、collections 类
这个和前面讲到的collection的是2个东西,conetcion是一个单列集合的接口,而conections是集合的工具类。
该类是个静态类,可以直接使用类名来调用。
常用方法:
- public staticboolean addAll(Collection c, T... elements) `:往集合中添加一些元素。- `public static void shuffle(List list) 打乱顺序`:打乱集合顺序。- `public static void sort(List list)`:将集合中元素按照默认规则排序。- `public static void sort(List list,Comparator )`:将集合中元素按照指定规则排序。
代码示例:
public static void main(String[] args) { ArrayListlist = new ArrayList<>(); Collections.addAll(list, 123, 1243, 1354, 123); System.out.println(list); Collections.sort(list); System.out.println(list); }
以往的集合都是通过add一个一个的去添加数据,但是collections可以一次添加多个数据。
1、Map集合
在collection的一些协和,元素都是单独存在的,想集合存储一个个元素的方式存在。
而map中的集合,元素是成对存在的。每个元素都由键和值组成,通过键可以找到对应的值。已知实现类:
AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, RenderingHints, SimpleBindings, TabularDataSupport, TreeMap, UIDefaults, WeakHashMap
下面就来看最常用的几个实现类
Hashmap
HashMap:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需
要重写键的hashCode()方法、equals()方法。
map接口中的方法:
public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。public V get(Object key) 根据指定的键,在Map集合中获取对应的值。public SetkeySet() : 获取Map集合中所有的键,存储到Set集合中。public Set > entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)
Map接口中的集合都有两个泛型变量,在使用时,要为两个泛型变量赋予数据类型。两个泛型变量的数
据类型可以相同,也可以不同。代码:
public static void main(String[] args) { HashMapmap = new HashMap<>(); map.put("小明","18"); map.put("小j","48"); map.put("小x","88"); map.put("小g","98"); System.out.println(map.get("小明")); }
使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中。指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。
map集合遍历
map里面提供了一个获取所以键值的方法keyset。供我们遍历使用。
public static void main(String[] args) { HashMapmap = new HashMap<>(); map.put("狗子",18); map.put("二狗",17); map.put("狗蛋",16); Set keys = map.keySet(); for (String key : keys) { Integer value = map.get(key); System.out.println(value); } }
遍历键值对
Entry将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。
既然是键值的对象,那么肯定会提供获取的方法。
public K getKey():获取Entry对象中的键。public V getValue()`:获取Entry对象中的值。
代码:
public static void main(String[] args) { // 创建Map集合对象 HashMapmap = new HashMap (); // 添加元素到集合 map.put("狗子", "18"); map.put("狗蛋", "17"); map.put("二狗", "16"); // 获取 所有的 entry对象 entrySet Set > entries = map.entrySet(); for (Map.Entry entry : entries) { System.out.println(entry); //遍历 System.out.println("key"+entry.getKey()); System.out.println("value"+entry.getValue()); } }
LinkedHashMap
Hashmap的存放是无序的,如果需要有序存储数据的话,就需要用到LinkedHashMap。
public static void main(String[] args) { LinkedHashMaplist = new LinkedHashMap<>(); list.put("狗子","18"); list.put("二狗","17"); list.put("狗蛋","16"); Set > entries = list.entrySet(); for (Map.Entry entry : entries) { System.out.println(entry); } }
发表评论
最新留言
关于作者
