您的位置:首页 > 其它

Set,List集合及其子类/泛型/增强for循环

2017-11-12 22:19 381 查看

1.ArrayList

1.ArrayList集合底层数据结构是用数组的形式,增删慢,查找快,线程不安全,但执行效率高

boolean add(E e)

将指定的元素添加到此列表的尾部。

void clear()

移除此列表中的所有元素。

int size()

返回此列表中的元素数。

Object[] toArray()

按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。

boolean remove(Object o)

移除此列表中首次出现的指定元素(如果存在)。

boolean isEmpty()

如果此列表中没有元素,则返回 true

E get(int index)

返回此列表中指定位置上的元素。

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

/**
* 需求:ArrayList去除集合中字符串的重复元素
*      1)首先创建一个集合
*      2)给集合中添加很多重复元素
*      3)再次创建一个新集合
*      4)获取迭代器遍历
*      5)获取到该集合中的每一个元素
*              判断新集合中是否包含这些有素
*              有,不搭理它
*              没有.说明不重复,添加进来
*       6)遍历新集合
* @author Apple
*/
public class ArrayListTest {

public static void main(String[] args) {

//1)创建一个集合
ArrayList array = new ArrayList() ;

//2)给集合中添加多个重复元素
array.add("hello") ;
array.add("hello") ;
array.add("hello") ;
array.add("world") ;
array.add("world") ;
array.add("world") ;
array.add("Java") ;
array.add("Java") ;
array.add("hello") ;
array.add("Javaweb") ;
array.add("JavaEE") ;
array.add("JavaEE") ;

//3)创建一个新的集合
ArrayList newArray = new ArrayList() ;

//4)遍历旧集合,获取当前迭代器对象
Iterator it = array.iterator() ;
while(it.hasNext()){
String s = (String) it.next() ;

//拿到了每一个字符串元素
//判断新集合是否包含旧集合中的元素

if(!newArray.contains(s)){
//不包含,就将元素直接添加到新集合中
newArray.add(s) ;
}
}

//遍历新集合
Iterator it2 = newArray.iterator() ;
while(it2.hasNext()){
String s = (String) it2.next() ;
System.out.println(s);
}
}
}


2.LinkedList

1.LinkedList集合底层数据结构是用链表实现的,增删快,查找慢,线程不安全,执行效率高

特有功能:

添加功能:

public void addFirst(E e);

//添加元素在第一个位置

public void addLast(E e);

//添加元素在最后一个位置

获取功能:

public Object getFirst();

//获取第一个位置的元素

public Object getLast();

//获取最后一个位置的元素

删除功能

public Object removeFirst()

//删除第一个位置的元素

public Object removeLast();

//删除最后一个位置的元素

import java.util.Iterator;
import java.util.LinkedList;

//需求:使用LinkedList模拟一个栈结构的特点
//表达的意思:自定义栈集合类,然后使用LinkedList的一些特有功能模拟栈结构特点
public class LinkedListDemo {

public static void main(String[] args) {

//创建LinkedList集合的对象
LinkedList link = new LinkedList() ;
//LinkedList集合的特有功能:addFirst(Object e)
//栈结构的特点:先进后出
link.addFirst("hello") ;
link.addFirst("world") ;
link.addFirst("java") ;

Iterator it = link.iterator() ;
while(it.hasNext()){
String s = (String)it.next() ;
System.out.println(s);
}
}
}


3.Vector

1.Vector集合底层是用数组实现的,增删慢,查找快,线程安全,执行效率低

2.特有功能

特有功能:

public void addElement(E obj)——->相当于:add(Object e)

public Enumeration elements()—–>相当于:Iterator iterator() ;

Enumeration接口:向量的组件枚举有两个方法

boolean hasMoreElements():——>相当于:hasNext()

Object nextElement():———–>相当于:next();

public class VectorDemo {

public static void main(String[] args) {

//创建一个Vector集合对象
Vector v = new Vector() ;

//添加元素
//public void addElement(E obj)
v.addElement("hello");
v.addElement("hello");
v.addElement("world");
v.addElement("Java");

//public Enumeration<E> elements()----->相当于:Iterator iterator() ;
Enumeration en = v.elements() ;
//遍历元素
/**
* boolean hasMoreElements():------>相当于:hasNext()
Object nextElement():----------->相当于:next();
*/
while(en.hasMoreElements()){
//获取元素
String s = (String)en.nextElement() ;
System.out.println(s);
}
}
}


4.泛型

1.把数据类型的明确提前到了创建对象或者调用方法的时候明确的一种特殊类型,

格式<参数类型>//此处的参数类型必须是引用类型

泛型的好处:

(1)泛型的出现将运行时期异常提前到了编译时期

(2)解决了黄色警告线问题(编译是有警告)

(3)获取数据的时候不用强制类型转换

(4)提高了程序的安全性

public class GenericDemo2 {

public static void main(String[] args) {

//创建一个ArrayList集合对象
ArrayList<String> array = new ArrayList<String>() ;//jdk7特性:泛型推断!:建议:后面永远给出类型

//给集合中添加元素
array.add("hello") ;
array.add("world") ;
array.add("java") ;
//      array.add(10) ;

//获取迭代器对象并遍历
Iterator<String> it = array.iterator() ;
//遍历
while(it.hasNext()){
//不用强制类型转换了
String s = it.next() ;
System.out.println(s);
}

}
}


5.增强for循环

1.格式

for(数组或者集合的数据类型 变量名:对象名)

{//输出变量名

}

2.增强for循环的优点

可以替代迭代器 代码简化了

3.增强for循环的缺点

被遍历的集合对象不能为空

public class ForDemo2 {

public static void main(String[] args) {

// 创建ArrayList集合
ArrayList<Student> array = new ArrayList<Student>();

// 创建学生对象
Student s1 = new Student("高圆圆", 27);
Student s2 = new Student("高圆圆", 20);
Student s3 = new Student("邓超", 29);
Student s4 = new Student("邓超", 25);

// 给集合中添加元素
array.add(s1) ;
array.add(s2) ;
array.add(s3) ;
array.add(s4) ;

//普通for循环:size()和get(int index)相结合
for(int x =0 ; x < array.size() ; x ++){
Student s = array.get(x) ;
System.out.println(s.getName()+"---"+s.getAge());
}

System.out.println("-----------------------");

//Collection集合的迭代器:Iterator iterator();
Iterator<Student> it = array.iterator() ;
while(it.hasNext()){
Student s = it.next() ;
System.out.println(s.getName()+"----"+s.getAge());
}

System.out.println("-----------------------");

//增强for遍历
for(Student s : array){
System.out.println(s.getName()+"----"+s.getAge());
}
}
}


6.Set

Set接口是collection集合的子类

Set:底层数据结构是一个哈希表,能保证元素是唯一的,元素不重复!

它通过它的子实现了HashSet集合去实例化,HashSet集合底层是HashMap集合的实例!

public class SetDemo {

public static void main(String[] args) {

//创建Set集合对象
Set<String> set = new HashSet<String>() ;

//添加元素
set.add("hello");
set.add("java") ;
set.add("java") ;
set.add("world") ;
set.add("world") ;
set.add("world") ;

//增强for遍历
for(String s :set){
System.out.println(s);
}
}
}


7.HashSet

底层依赖与HashCode()和equals()这两个方法来保证元素的唯一性

//源码
interface Collection{}
interface Set Extends Collection{

}

class HashSet<E> implements Set<E>{
private transient HashMap<E,Object> map;

//HashSet集合的无参构造方法
public HashSet() {
map = new HashMap<>();
}

//HashSet集合的添加功能:
public boolean add(E e) {//"hello","world","world"
return map.put(e, PRESENT)==null;//"hello","world","world"= e
}
}

class HashMap<K,V> implements Map<K,V>{

//HashMap集合添加元素的功能
public V put(K key, V value) {//k="hello","world"
if (table == EMPTY_TABLE) {//table:判断哈希表示==空表
inflateTable(threshold);
}
if (key == null)//元素是空
return putForNullKey(value);
int hash = hash(key);//携带当前HashSet集合中的元素:"hello","world","world" :第一次的world和第二次world返回到HashCode值一样
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {//for循环:遍历键值对象的(Map集合遍历)
Object k;
if (ase.hh == hash && ((k = e.key) == key || key.equals(k))) {
//e:每一个元素:要判断他们的hashCode值是否一样,如果hashCode值一样还要判断他们的equals()方法,而对于String类型来说,底层已经重写了
Object中的equals()方法,所以比较多是内容是否相同
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue; //hashCode()值一样,在比较内容是否相同,(如果相同),直接返回第一次存储的"world"
}
}

modCount++;
addEntry(hash, key, value, i);
return null;
}

//hash()方法
final int hash(Object k) {"hello","world","world
int h = hashSeed;
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}

h ^= k.hashCode();//每一个元素都要调用:hashCode();是Object类中的方法

// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
}


8.TreeSet

TreeSet底层依赖于TreeMap的实例,而TreeMap依赖于红黑树(二叉树)结构

1.自然排序

如果存储自定义对象,必须实现compareable接口(实现compareTo()方法)

//在学生类中重写compareTo()
public int compareTo(Student s) {
//      return 0;
//排序的代码了,需要定义排序的条件
//主要条件:按照学生的年龄从小到大进行排序
int num =s.age - this.age ;//年龄从大到小
//      return num ;
//当num==0认为年龄一样,年龄一样,不代表姓名的的内容是否相同,需要自己给出次要条件
int num2 = num==0 ? this.name.compareTo(s.name): num ;
return num2 ;
}

}


2.比较器排序

方式1:自定义一个类,类实现Comparator接口,作为子实现类

方式2:可以使用接口的匿名内部类来实现:开发中,由于减少代码书写量,不需要自定义接口的子实现类,直接这种格式!

格式

new 接口名或者类名(){

重写方法() ;

}

public class TreeSetTest {

public static void main(String[] args) {

// 创建TreeSet集合对象,使用有参构造
// 比较器排序匿名内部类的方式
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {

@Override
public int compare(Student s1, Student s2) {
// 主要条件:总分从高到到第进行排序
int num = s2.getSum() - s1.getSum();

// 总分相同,不一定语文成绩相同,比较语文成绩
int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;

// 总分相同,语文成绩相同,比较数学成绩
int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;

// 总分相同,语文成绩相同,数学相同,比较英语
int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3;

// 总分以及各科成绩都相同,不一定是同一个人,姓名内容是否相同
int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName())
: num4;
return num5;
}
});

System.out.println("录入学生信息开始:");
// 键盘录入5个学生的信息,姓名,语文成绩,数学成绩,英语成绩
for (int x = 1; x <= 5; x++) {
// 创建键盘录入对象
// 为了方便录入数据,数据类型都使用String类型接收
Scanner sc = new Scanner(System.in);
System.out.println("请输入第" + x + "个学生的姓名:");
String name = sc.nextLine();
System.out.println("请输入第" + x + "个学生的语文成绩:");
String chineseString = sc.nextLine();
System.out.println("请输入第" + x + "个学生的数学成绩:");
String mathString = sc.nextLine();
System.out.println("请输入第" + x + "个学生的英语成绩:");
String englishString = sc.nextLine();

// 创建一个学生对象,把这些信息封装到学生对象中
Student s = new Student();
s.setName(name);
s.setChinese(Integer.parseInt(chineseString));
s.setMath(Integer.parseInt(mathString));
s.setEnglish(Integer.parseInt(englishString));

// 将学生对象添加到集合中
ts.add(s);
}

System.out.println("学生信息录入结束:");
System.out.println("学生信息总分从高到底排列数学如下:");
System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩");

// 增强for遍历集合
for (Student s : ts) {
System.out.println(s.getName() + "\t" + s.getChinese() + "\t"
+ s.getMath() + "\t" + s.getEnglish());
}
}
}


LinkedHashSet

*

* 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。

*

* LinkedHashSet集合:

* 由哈希表保证元素的唯一性

* 由链接列表来保证元素的有序性!

* `public class LinkedHashSetDemo {

public static void main(String[] args) {

//创建LinkedHashSet集合对象
LinkedHashSet<String> link = new LinkedHashSet<String>();

//给集合中添加元素
link.add("hello") ;
link.add("world") ;
link.add("world") ;
link.add("Java") ;
link.add("Java") ;
link.add("JavaWeb") ;
link.add("JavaWeb") ;

//遍历集合
for(String s: link){
System.out.println(s);
}
}


}`
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐