Collection接口

API

Modifier and Type

Method and Description

boolean

add(E e) 确保此集合包含指定的元素(可选操作)。

boolean

addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合(可选操作)。

void

clear() 从此集合中删除所有元素(可选操作)。

boolean

contains(Object o) 如果此集合包含指定的元素,则返回 true

boolean

containsAll(Collection<?> c) 如果此集合包含指定 集合中的所有元素,则返回true。

boolean

equals(Object o) 将指定的对象与此集合进行比较以获得相等性。

int

hashCode() 返回此集合的哈希码值。

boolean

isEmpty() 如果此集合不包含元素,则返回 true

Iterator<E>

iterator() 返回此集合中的元素的迭代器。

default Stream<E>

parallelStream() 返回可能并行的 Stream与此集合作为其来源。

boolean

remove(Object o) 从该集合中删除指定元素的单个实例(如果存在)(可选操作)。

boolean

removeAll(Collection<?> c) 删除指定集合中包含的所有此集合的元素(可选操作)。

default boolean

removeIf(Predicate<? super E> filter) 删除满足给定谓词的此集合的所有元素。

boolean

retainAll(Collection<?> c) 仅保留此集合中包含在指定集合中的元素(可选操作)。

int

size() 返回此集合中的元素数。

default Spliterator<E>

spliterator() 创建一个Spliterator在这个集合中的元素。

default Stream<E>

stream() 返回以此集合作为源的顺序 Stream

Object[]

toArray() 返回一个包含此集合中所有元素的数组。

<T> T[]

toArray(T[] a) 返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。

一、List

元素有序、可重复的集合;“动态数组”

添加元素所在的类要重写equals方法

一、ArrayList

简单源码分析:

源码方法

作用或实现

ArrayList list = new ArrayList();

在底层创建长度位10的Object数组elementData;在JDK8中,使用无参构造器是,不会创建长度为10的数组,而是{};在第一次调用add()时,会自动创建长度为10的数组;后面的操作与之前一致;延迟数组创建,可节省内存

list.add(“aaa”);

elementData[0] = “aaa”;当elementData的长度不够时,会扩容数组为原来的1.5倍,并将原来的数据copy到扩容后的数组

ArrayList list = new ArrayList(5);

有参构造器;传入参数后会创建一个该大小的数组;在已知大小的情况下建议使用该构造器。

常用方法:(除去Collection接口中的方法)

返回值

方法

描述

void

add(int index, E element)`

在此列表中的指定位置插入指定的元素。

void

addAll(int index, Collection<? extends E> c)

将指定集合中的所有元素插入到此列表中,从指定的位置开始。

E

get(int index)

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

int

indexOf(Object o)

返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。

int

lastIndexOf(Object o)

返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。

ListIterator

listIterator(int index)

从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。

E

remove(int index)

删除该列表中指定位置的元素。

E

set(int index, E element)

用指定的元素替换此列表中指定位置的元素。

List

subList(int fromIndex, int toIndex)

返回此列表中指定的 fromIndex (包括)和 toIndex之间的独占视图。

排序:

List list = Arrays.asList(2,5,94,3,5,4,7,5,4,321,5);

list.sort(Comparator.naturalOrder());   //从小到大

list.sort(Comparator.reverseOrder());    //从大到小

List遍历:**

List<Integer> list = Arrays.asList(2,5,94,3,5,4,7,5,4,321,5);

        //方式一:普通循环
        for (int i=0; i<list.size(); i++){
            System.out.println(list.get(i));
        }

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

        //方式二:增强for循环
        for (int i : list) {
            System.out.println(i);
        }

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

        //方式三:迭代器
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

二、LinkedList

简单源码分析:

源码方法

作用或实现

transient int size = 0; transient Node first; transient Node last;

创建一个LinkedList时,会指明链表的长度、第一个节点(临时)和最后一个节点(临时)

private static class Node {…}

节点的内部类,用于声明一个节点;包括由上一个节点、数据、下一个节点

添加元素(add()会方法调用该方法)

void linkLast(E e) {
        final Node<E> l = last;    //获取最后一个节点
        final Node<E> newNode = new Node<>(l, e, null);     //构建一个新的节点,l为prev,next为空
        last = newNode;          //将新的节点作为最后一个节点
        if (l == null)           //如果最后一个节点是null,则将新的节点作为第一个节点
            first = newNode;
        else                      //否则,最后一个节点的next指向新的节点
            l.next = newNode;
        size++;
        modCount++;
    }

常用方法:(LinkedList特有的方法)

返回值

方法

描述

void

addLast(E e)

将指定的元素追加到此列表的末尾。

void

addFirst(E e)`

在该列表开头插入指定的元素。

E

getFirst()

返回此列表中的第一个元素。

E

getLast()

返回此列表中的最后一个元素。

LinkedList可以充当对或栈,所以具有一些符合栈和队列特性的方法

boolean

offer(E e) 将指定的元素添加为此列表的尾部(最后一个元素)。

boolean

offerFirst(E e) 在此列表的前面插入指定的元素。

boolean

offerLast(E e) 在该列表的末尾插入指定的元素。

E

peek() 检索但不删除此列表的头(第一个元素)。

E

peekFirst() 检索但不删除此列表的第一个元素,如果此列表为空,则返回 null

E

peekLast() 检索但不删除此列表的最后一个元素,如果此列表为空,则返回 null

E

poll() 检索并删除此列表的头(第一个元素)。

E

pollFirst() 检索并删除此列表的第一个元素,如果此列表为空,则返回 null

E

pollLast() 检索并删除此列表的最后一个元素,如果此列表为空,则返回 null

E

pop() 从此列表表示的堆栈中弹出一个元素。

void

push(E e) 将元素推送到由此列表表示的堆栈上。


三、Vector

较少使用。创建时会直接创建长度为10的数组(jdk7、8都是),扩容会变为原来的两倍

四、ArrayList、LinkedList、Vector的异同

  • 同:三者都是实现了List接口;存储结构都是有序的、可重复的
  • 不同:
  1. Vector效率低(线程安全);其他的效率高(线程不安全)
  2. LinkedList适用于增加和删除(底层由双向链表实现);ArrayList由Object[ ]实现,适合数据的添加和查找;Vector底层由Object[] elementData实现


二、Set:

元素无序、不可重复的集合;set接口中没有新定义方法

在使用SET时,要重写所添加对象所在类的equals和hashCode方法;尽可能保证两个方法的一致,即如果equals的结果为false,则二者的hashcode也应该不一样

一、HashSet

*无序:不等于随机;底层使用数组实现,但是不根据数组的索引添加,而是根据数据的hashcode方法获得的值来添加

*不可重复性:保证添加的元素按照equals比较时,不能返回true;即equals比较结果必须为不相同

添加元素过程理解:1.首先调用待添加对象所在类的hashcode方法计算hash值;2.根据hash值使用算法计算出该值在hashset底层数组中的具体位置;3.如果在数组中的该位置没有元素,则直接将该值添加至数组中,即完成添加;4.如果数组的该位置已有元素,则比较其hash值,如果不同,在该位置使用链表存储这些元素;5.如果hash值也行同,则调用待添加对象所在类中的equals方法,如果返回true,则该值重复,不在添加,如果返回false,则在该位置的链表中添加该值

API:同Collection接口中的方法

Set遍历:

Set set = new HashSet();
        set.add(1);
        set.add("aaa");
        set.add(false);
        set.add(55);

	    //方法一
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

		System.out.println("--------------------");
		//方法二
        for (Object o: set) {
            System.out.println(o);
        }

二、LinkedHashSet

LinkedHashSet存储的方式与HashSet一样;但是遍历结果与添加的顺序相通,原因为:在添加数据的同时,其维护了添加数据的先后顺序,具体实现为每个元素都具有头和尾,分别指向前一个元素和后一个元素

优点:频繁的遍历效率高于HashSet

三、TreeSet

TreeSet中的存储结构为红黑树

Set中添加的数据必须是同一个类的数据

可以按照的对象的指定属性排序

注:TreeSet中的比较对象是否相同不适用equals,而使用compareTo( )/Compare()的返回值是否为0,0表示相同;

使用Comparable接口规定排序的规则(自然排序):

//对象类persion,其他方法已省略,只关注compareTo方法的重写
public class persion implements Comparable{
    private String name;
    private int age;

    public persion(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public int compareTo(Object o) {
        if(o instanceof persion){
            persion p = (persion)o;
            if(this.age != p.age){
                return Integer.compare(this.age,p.age);
            }else{
                return this.name.compareTo(p.name);
            }
        }else{
            throw new RuntimeException("传入参数错误");
        }
    }
}
//实现
 public static void main(String[] args) {
        Set set = new TreeSet();
        set.add(new persion("zhangsan",15));
        set.add(new persion("lisi",20));
        set.add(new persion("wangwu",65));
        set.add(new persion("liuiz",53));

        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
/*输出:
persion{name='zhangsan', age=15}
persion{name='lisi', age=20}
persion{name='liuiz', age=53}
persion{name='wangwu', age=65}

*/

使用Comparator实现定制排序:

public static void main(String[] args) {
        Comparator com = new Comparator(){

            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof persion && o2 instanceof persion){
                    persion p1 = (persion)o1;
                    persion p2 = (persion)o2;
                    return Integer.compare(p1.getAge(),p2.getAge());
                }else{
                    throw new RuntimeException("出入参数错误");
                }
            }
        };

        Set set = new TreeSet(com);
        set.add(new persion("zhangsan",15));
        set.add(new persion("lisi",20));
        set.add(new persion("wangwu",65));
        set.add(new persion("liuiz",53));


        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

四、HashSet、LinkedHashSet、TreeSet异同

  1. HashSet:为set的主要实现类;线程不安全;可存放null值
  2. LinkedHashSet:为HashSet的子类;遍历时可以按照添加数据时的顺序来遍历;频繁的遍历效率高于HashSet
  3. TreeSet:可以按照的对象的指定属性排序

Map接口

key–value

一、HashMap

hashMap结构理解

  • key:无序的、不可重复的;可以理解为set存储 >>>key所在的类要重写equals()和hashCode()方法
  • value:无序的、可重复的;可以理解为Collection存储 >>>value所在的类要重写equals方法
  • enrty:key-value构成entry对象;entry无序的、不可重复的;可以理解为使用set存储

java 类中函数返回值为本类_System

底层实现:

(jdk7=数组+链表;jdk8=数组+链表+红黑树)

jdk7:

源码

描述

Map map = new HashMap();

底层创建长度为16的数组;类型为Entry [ ] table

map.put(k1,v1);

1.根据key所在类的hashCode方法,计算hash值,通过计算获得其在数组中的存放位置;2.如果该位置为空,则将该k-v放入该位置;3.如果该位置已有数据,则比较他们的hash值,如果不同,则添加该k-v;如果相同,则调用待添加k所在类的equals方法:如果返回false,则添加成功;如果返回true,使用v替换该位置的原来的value(覆盖)。(如果原位置已有元素,则以链表的形式添加新的元素;涉及扩容时:扩容为原来的两倍【超出临界值且该位置已有元素才会扩容】,并复制原来的数据)

jdk8:

  1. new HashMap();底层没有创建长度为16的数组
  2. 底层使用的数组为Node[ ];
  3. 首次调用put()方法时会创建长度为16的数组;
  4. 当数组的某一个索引位置的元素数量>8 ,且当数组长度超过64时,此索引位置上的元素改用红黑树存储

常用API:

返回值

方法

描述

void

clear()

从这张地图中删除所有的映射。

boolean

containsKey(Object key)

如果此映射包含指定键的映射,则返回true。

boolean

containsValue(Object value)

如果此地图将一个或多个键映射到指定值,则返回 true 。

V

get(Object key)

返回到指定键所映射的值,或 null如果此映射包含该键的映射。

boolean

isEmpty()

如果此地图不包含键值映射,则返回 true。

V

put(K key, V value)

将指定的值与此映射中的指定键相关联。

void

putAll(Map<? extends K,? extends V> m)

将指定地图的所有映射复制到此地图。

V

remove(Object key)

从该地图中删除指定键的映射(如果存在)。

boolean

remove(Object key, Object value)

仅当指定的密钥当前映射到指定的值时删除该条目。

V

replace(K key, V value)

只有当目标映射到某个值时,才能替换指定键的条目。

boolean

replace(K key, V oldValue, V newValue)

仅当当前映射到指定的值时,才能替换指定键的条目

int

size()

返回此地图中键值映射的数量。

Collection

values()

返回此地图中包含的值的Collection视图。

Set<Map.Entry<K,V>>

entrySet()

返回此地图中包含的映射的Set视图。

Set

keySet()

返回此地图中包含的键的Set视图。

hashMap的遍历:

public static void main(String[] args) {
        Map<String,Integer> map = new LinkedHashMap();
        map.put("a",1);
        map.put("b",3);
        map.put("c",3);

        //遍历map中的key
        Set<String> keySet = map.keySet();
        Iterator<String> iterator = keySet.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

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

        //遍历map中的value
        Collection<Integer> values = map.values();
        Iterator<Integer> iterator1 = values.iterator();
        while(iterator1.hasNext()){
            System.out.println(iterator1.next());
        }

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

        //遍历map:方法一
        for (Map.Entry<String,Integer> e: map.entrySet()) {
            System.out.print(e.getKey());
            System.out.print("   ");
            System.out.print(e.getValue());
            System.out.println();
        }

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

        //遍历map:方法二
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator2 = entries.iterator();
        while(iterator2.hasNext()){
            Map.Entry e = (Map.Entry)iterator2.next();
            System.out.print(e.getKey());
            System.out.print("   ");
            System.out.print(e.getValue());
            System.out.println();
        }

    }

/*输出:
a
b
c
-----------------
1
3
3
-----------------
a   1
b   3
c   3
-----------------
a   1
b   3
c   3
*/

二、LinkedHashMap

是HashMap的子类,方法都一样,知识多了两个before、after指针,当频繁使用遍历时效率更高

三、TreeMap

*添加的数据类型必须都是同一类型的

自然排序实现(类实现Comparable接口):

//传入的参数类,关注接口的实现与方法的重写
public class student implements Comparable{    //实现Comparable接口
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        student student = (student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public student() {
    }

    public student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int compareTo(Object o) {    //重写compareTo方法,将根据重写的逻辑来排序
        if(o instanceof student){
            student s = (student)o;
            return this.name.compareTo(s.name);
        }else{
            throw new RuntimeException("参数错误");
        }
    }
}
//遍历TreeMap查看排序
public static void main(String[] args) {
        TreeMap<student,Integer> map = new TreeMap();
        student s1 = new student("shangsan", 10);
        student s2 = new student("lisi", 15);
        student s3 = new student("wangwu", 11);
        student s4 = new student("liu", 120);

        map.put(s1,1);
        map.put(s2,2);
        map.put(s3,3);
        map.put(s4,4);

        for (Map.Entry<student,Integer> e :map.entrySet()) {
            System.out.print(e.getKey().getName());
            System.out.print("  ");
            System.out.print(e.getValue());
            System.out.println();
        }
    }
/*输出:
lisi  2
liu  4
shangsan  1
wangwu  3
*/

定制排序(new TreeSet()时传入Comparator):

public static void main(String[] args) {
        Comparator<student2> com = new Comparator(){    //创建Comparator对象,并重写compare方法

            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof student2){
                    student2 s1 = (student2)o1;
                    student2 s2 = (student2)o2;
                    return Integer.compare(s1.getAge(),s2.getAge());
                }else{
                    throw new RuntimeException("参数错误");
                }
            }
        };

        TreeMap<student2,Integer> map = new TreeMap(com);    //将创建的Comparator对象传入TreeMap构造器,将根据此规则排序
        student2 s1 = new student2("shangsan", 10);
        student2 s2 = new student2("lisi", 15);
        student2 s3 = new student2("wangwu", 11);
        student2 s4 = new student2("liu", 120);

        map.put(s1,1);
        map.put(s2,2);
        map.put(s3,3);
        map.put(s4,4);

        for (Map.Entry<student2,Integer> e :map.entrySet()) {
            System.out.print(e.getKey().getName());
            System.out.print("  ");
            System.out.print(e.getValue());
            System.out.println();
        }
    }
/*输出:
shangsan  1
wangwu  3
lisi  2
liu  4
*/

五、Hashtable:

Properties:作为Hashtable的子类(是一种map)

多用于配置文件

###配置文件jdbc.properties信息
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mytest?serverTimezone=UTC&useSSL=false
jdbc.username=root
jdbc.password=root
//加载配置文件
public static void main(String[] args) {
        Properties properties = new Properties();
        try {
            FileInputStream fis = new FileInputStream("jdbc.properties");
            properties.load(fis);
            String driver = properties.getProperty("jdbc.driver");
            String url = properties.getProperty("jdbc.url");
            String username = properties.getProperty("jdbc.username");
            String password = properties.getProperty("jdbc.password");
            System.out.println(driver + "  " + url + "   "+ username +"   "+ password);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
/*输出:
com.mysql.cj.jdbc.Driver  jdbc:mysql://localhost:3306/mytest?serverTimezone=UTC&useSSL=false   root   root
*/

区别:

  • HashMap:Map接口的主要实现类;线程不安全,效率高;可以存储null的key或value
  • LinkedHashMap:作为HashMap的子类;保证在遍历map元素时实现按照添加时的顺序(添加有两个指针指向前一个和后一个元素);频繁遍历效率高
  • TreeMap:添加的key-value可以按照key来实现自然排序或定制排序
  • Hashtable:线程安全,效率低;不可以存储null的key或value
  • Properties:作为Hashtable的子类;常用来作为配置文件。key和value都是String

Collections工具类

Collections用于操作set、list、map的工具类

常用方法:

  • reverse(List<?> list) 反转指定列表中元素的顺序。
List<String> list1 = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
        Collections.reverse(list1);
        for (String s:list1) {
            System.out.println(s);
        }
/*输出:
eee
ddd
ccc
bbb
aaa
*/
  • shuffle(List<?> list)
List<String> list1 = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
        Collections.shuffle(list1);
        for (String s: list1) {
            System.out.println(s);
        }
/*输出:  随机序列
bbb
ddd
ccc
eee
aaa
*/
  • sort(List list) 根据其元素的natural ordering对指定的列表进行排序(简易理解为:从小到大)
  • sort(List list, Comparator<? super T> c) 根据指定的比较器引起的顺序对指定的列表进行排序。
List<String> list1 = Arrays.asList("aaa", "ccc", "ddd", "bbb","eee");
        Collections.sort(list1, Comparator.reverseOrder());    //倒叙
        for (String s: list1) {
            System.out.println(s);
        }
        System.out.println("--------------");
        Collections.sort(list1, Comparator.naturalOrder());    //自然排序
        for (String s: list1) {
            System.out.println(s);
        }
  • swap(List<?> list, int i, int j) 交换指定列表中指定位置的元素。
List<String> list1 = Arrays.asList("aaa", "ccc", "ddd", "bbb","eee");  
        Collections.swap(list1,0,4);    //交换索引为0和4的元素的位置
        for (String s: list1) {
            System.out.println(s);
        }
/*输出:
eee
ccc
ddd
bbb
aaa
*/
  • max(Collection<? extends T> coll) 根据其元素的 自然顺序返回给定集合的最大元素。
List<String> list1 = Arrays.asList("ccc", "ddd", "bbb","eee","aaa");
        String max = Collections.max(list1);
        System.out.println(max);    //eee

        HashSet<Integer> set = new HashSet<>();
        set.add(5);
        set.add(8);
        set.add(4);
        Integer max1 = Collections.max(set);
        System.out.println(max1);   //8
  • max(Collection<? extends T> coll, Comparator<? super T> comp) 根据指定的比较器引发的顺序返回给定集合的最大元素。
List<String> list1 = Arrays.asList("ccc", "ddd", "bbb","eee","aaa");
        String max = Collections.max(list1,new Comparator(){

            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof String && o2 instanceof String){
                    String s1 = (String)o1;
                    String s2 = (String)o2;
                    return - s1.compareTo(s2);
                }else{
                    throw new RuntimeException("参数错误");
                }
            }
        });
        System.out.println(max);    //eee

        HashSet<Integer> set = new HashSet<>();
        set.add(5);
        set.add(8);
        set.add(4);
        Integer max1 = Collections.max(set,Comparator.reverseOrder());
        System.out.println(max1);   //8
  • min(Collection<? extends T> coll) 根据其元素的 自然顺序返回给定集合的最小元素。
  • min(Collection<? extends T> coll, Comparator<? super T> comp) 根据指定的比较器引发的顺序返回给定集合的最小元素。
  • frequency(Collection<?> c, Object o) 返回指定集合中与指定对象相等的元素数。
List<String> list1 = Arrays.asList("ccc", "ddd", "bbb", "ddd","eee","aaa", "ddd");
        int ddd = Collections.frequency(list1, "ddd");
        System.out.println(ddd);    //3
  • replaceAll(List list, T oldVal, T newVal) 将列表中一个指定值的所有出现替换为另一个。
List<String> list1 = Arrays.asList("ccc", "ddd", "bbb", "ddd","eee","aaa", "ddd");
        Collections.replaceAll(list1,"ddd","replace");
        for (String s: list1) {
            System.out.println(s);
        }
/*输出:
ccc
replace
bbb
replace
eee
aaa
*/
  • synchronizedXXX(XXX c) 返回由指定集合支持的同步(线程安全)集合
    例如List:
List<String> list1 = Arrays.asList("ccc", "ddd", "bbb", "ddd","eee","aaa", "ddd");
        List<List<String>> lists = Collections.singletonList(list1);
List<String> list1 = Arrays.asList("ccc", "ddd", "bbb", "ddd","eee","aaa", "ddd");
    int ddd = Collections.frequency(list1, "ddd");
    System.out.println(ddd);    //3
  • replaceAll(List list, T oldVal, T newVal) 将列表中一个指定值的所有出现替换为另一个。
List<String> list1 = Arrays.asList("ccc", "ddd", "bbb", "ddd","eee","aaa", "ddd");
        Collections.replaceAll(list1,"ddd","replace");
        for (String s: list1) {
            System.out.println(s);
        }
/*输出:
ccc
replace
bbb
replace
eee
aaa
*/
  • synchronizedXXX(XXX c) 返回由指定集合支持的同步(线程安全)集合
    例如List:
List<String> list1 = Arrays.asList("ccc", "ddd", "bbb", "ddd","eee","aaa", "ddd");
        List<List<String>> lists = Collections.singletonList(list1);