JAVA基础(六)

JAVA基础(六)

Arrays类:

  1. toString 返回数组的字符串形式 Arrays.toString(arr)

  2. sort排序 (自然排序和定制排序)

  3. binarySearch 通过二分搜索法进行查找,要求必须排好序 int index =Arrays.binarySearch(arr,3);

  4. copyOf 数组元素的复制

    Integer [] newArr = Arrays.copyOf(arr,arr.length);
    //如果拷贝长度>arr.length就在新数组的后面增加Null
    //如果拷贝的长度<0 就抛出异常NegativeArraySizeException
    //该方法的底层使用的是System.arraycopy()
    
  5. fill 数组元素的填充

  6. equals 比较两个数组元素是否完全一致。

  7. asList 将一组值,转换成list

    List<Integer> asList = Arrays.List(2,4,5,6,9);
    

System类:

  1. exit(0)退出当前程序,0表示是正常状态
  2. arraycopy: 复制数组元素,比较适合底层调用,一般使用Arrays.copyOf完成复制数组。
  3. currentTimeMillens:返回当前时间距离1970- 1 -1 的毫秒数
  4. gc:运行垃圾回收机制 System.gc();

BigInteger和BigDecimal类

BigInteger 适合保存比较大的整型。常用方法 。add 加 subtract 减 multiply 乘 divide除

BigDecimal适合保存精度更高的浮点型(小数)

日期类:

  1. Date :精确到毫秒,代表特定的瞬间
  2. SimpleDateFormate:格式和解析日期的类SimpleDareDormat格式化和解析日期的具体类。它允许进行格式化(日期->文本)、解析(文本->日期)和规范化
  Date d1 =new Date();//获取当前系统时间
        Date d2 = new Date(92345);//通过指定毫秒数得到时间
        System.out.println(d1.getTime());//获取某个时间对应的毫秒数
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
        String format = sdf.format(d1);
        System.out.println(format);
//1、可以把一个格式化的String转换成对应的Date
//2、得到Date仍然在输出时,还在按照国外形式,如果希望指定格式输出,需要转换
//3、在把Sting->Date。使用的sdf 格式需要和你给的String的格式一样,否则回抛出异常
        String s= "1999年01月01日 10:20:30 星期一";
        Date parse = sdf.parse(s);
        System.out.println(sdf.format(parse));

Calendar()日历类:

        //1、Calendar 是一个抽象类,并且构造器是private
        //2、可以通过 getInstance()来获得实例
        //3、提供大量方法和字段
        //4、Calendar没有提供对应的格式化类,需要自己组合输出
		//5、如果需要24小时进制来获取时间,Calendar.Hour==>改成=>Calender.Hour_oF_DAy
        Calendar c = Calendar.getInstance();
       // System.out.println(c);
        System.out.println(c.get(Calendar.YEAR));
        //Calender返回月的适合,按0开始编号的。
        System.out.println(c.get(Calendar.MONDAY)+1);
        System.out.println(c.get(Calendar.DAY_OF_MONTH));
        System.out.println(c.get(Calendar.HOUR));
        System.out.println(c.get(Calendar.MINUTE));
        System.out.println(c.get(Calendar.SECOND));  

Date和Calendar存在的问题:

  1. 可变性:像日期和时间这样的类应该是不可变的
  2. 偏移性:Date 中的年份是从1900开始的 ,而且月份都是从0开始
  3. 格式化:格式化对Date有用,Calendar则不行
  4. 此外,它们也不是线程安全的,不能处理闰秒等(每隔2天,多1s)

第三代日期类常用方法:

LocalDate(日期/年月日)、LocalTime(时间/时分秒)、LocalDateTime(日期时间/年月日时分秒)JDK8加入

LocalDateTime ldt =LocalDateTime.now();//LocalDae.now();//LocalTime.now();
//使用DateTimeFormatter 对象来进行格式化
//创建DateTimeFormatter对象
DateTimeFormatter date = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm:ss");
String format = dateTimeFormatter.format(ldt);
//Instant 时间戳
//1.通过静态方法now()获取表示当前时间戳对象
Instant now = Instant.now();
System.out.println(now);
//2.通过from 可以把Instant转换成Date
Date date = Date.from(now);
//3.通过date的toInstant()可以把date转成Instant对象
Instant instant = date.toInstant();
//提供plus 和 minus 方法可以对当前时间进行加或减

数组:

1、长度开始时必须指定的,而且一旦指定,不能更改

2、保存的必须是同一类型的元素

3、使用数组进行增加/删除元素比较麻烦。

集合的好处:

  1. 可以动态保存任意多个对象。
  2. 提供了一系列方便的操作对象的方法:add、remove、set、get
  3. 使用集合添加,删除新元素

1、集合主要两组(单列集合,双列集合)

2、Collection 接口有两个重要的子接口List,Set ,他们的实现子类都

3、Map接口的实现子类,是双列集合,存放K-V

Collection接口和常用方法:

  1. public interface Collection<E> extends Iterable <E>
     //collection实现子类可以存放多个元素,每个元素可以是Object
     //有些Collection的实现类,可以存放重复的元素,有些不可以,有些是有序的(List),有些不是有序的(set)
     //Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的。   
    

Collection 接口遍历元素方式-使用Iterator(迭代器)

  1. Iterator对象称为迭代器,主要用于遍历Collection集合中的元素。
  2. 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器。
  3. Iterator仅用于遍历集合,Iterator本身不存放对象。
Iteraator iterator = coll.iterator();//得到一个集合的迭代器
//hasNext();判断是否还有下一个元素
while(iterator.hasNext()){
    //next();1、指针下移 2、将下移以后集合位置上的元素返回
    System.out.println(iterator.next());
}

增强for循环,可以替代iterator迭代器,特点:增强for就是简化版的iterator,本质一样。只用于遍历集合或数组。(底层就是迭代器)

基本语法:

for(元素类型 元素名称:集合名或数组名){

访问元素

}

List接口基本介绍:

List接口是Collection接口的子接口

  1. List 集合类中元素有序(即添加顺序和取出顺序一致)、且可重复。
  2. List集合中的每个元素都有其对应的顺序索引,即支持索引。(索引都是从0开始的)
  3. List容器中的元素对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
  4. 常用的实现类有:ArrayList、LinkedList、Vector。

ArrayList注意事项:

  1. permits all elements、including null、ArrayList 可以加入null,并且多个。
  2. ArrayList是由数组来实现数据存储的。
  3. ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高),多线程情况下,不建议使用ArrayList.

ArrayList的底层机制操作源码分析:

  1. ArrayList中维护了一个Object类型的数组elementData.transient Object[] elementData;//transient 表示瞬间、短暂的,表示该属性不会被序列化。
  2. 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0.第1次添加,则扩容elementData为10,如果需要再次扩容,则elementData为1.5倍。
  3. 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData1.5倍。

Vector的基本介绍:

public class Vector<E>
    extends AbstractList<E>
implements List<E>,RundomAccess,Cloneable,Serializable    

1、Vector底层也是一个对象数组 proected Object[] elementData;

2、Vector 是线程同步的,即线程安全,Vector类的操作方法带有synchronized

3、在开发中,需要线程同步安全时,考虑使用Vector。

Vector和ArrayList的比较:

底层结构版本线程安全(同步)效率扩容倍数
ArrrayList可变数组jdk1.2不安全、效率高如果有参构造1.5倍,如果是无参,第一次10,从第二次开始按1.5倍扩
Vector可变数组Object[]jdk1.0安全、效率不高如果是无参,默认10,满后,就按2倍扩容。如果指定大小,每次直接按2倍扩容

LinkedList的底层结构:

  1. LinkedList实现了双向链表和双端队列特征
  2. 可以添加任意元素(元素可以重复),包括null
  3. 线程不安全,没有实现同步。

LinkedList的底层操作机制:

  1. LinkedList底层维护了一个双向链表
  2. LinkedList中维护了两个属性first和last分别指向 首节点和尾节点
  3. 每个节点(Node对象),里面又维护prev、next、item三个属性,其中通过prev指向前一个节点,最终实现双向链表。
  4. 所以LinkedList元素的添加和删除,不是通过数组完成的,相对来说效率较高。
class Node {
    public Object item;//真正存放数据
    public Node next;//指向下一个结点
    public Node pre;//指向上一个结点
    public Node(Object name){
	this.item = name ;
    }
    public String toString(){
        return "Node name=" + item;
    }
}

ArrayList和LinkedList的比较:

底层结构增删效率改查的效率
ArrayList可变数组较低、数组扩容较高
LinkedList双向链表较高、通过链表追加较低

如何选择ArrayList和LinkedList:

  1. 如果改查的操作多,选择ArrayList
  2. 如果删除的操作多,选择LinkedList
  3. 在项目中,根据业务灵活选择,一个模块可以使用ArrayList,另外一个模块是LinkedList

Set接口和常用方法:

  1. 无序(添加和取出的顺序不一致),没有索引
  2. 不允许重复元素,最多包含一个Null
  3. Set接口是Collection的子接口,可以使用迭代器,增强for循环,不能索引的方式来获取。

HashSet接口实现类:

  1. HashSet实现了Set接口

  2. HashSet实现了是HashMap

  3. 可以存放Null值,但是只能有一个null

  4. HashSet不能保证元素是有序的,取决于hash后,再确定索引的结果,存储元素不能重复。

  5. 在执行add方法后,会返回一个boolean值,如果添加成功则返回true

  6. 可以通过remove指定删除哪个对象。

    HashSet set = new HashSet();
    set.add("lucy");//true
    set.add("lucy");//true
    
    set.add("new Dog()");//true
    set.add("new Dog()");//true
    class Dog{
        private String name;
    }
    set.add("new String("hsp")");//true
    set.add("new String("hsp")");//false,加不了
    

HashSet底层机制说明:

分析HashSet底层是HashMap,HashMap底层是(数组+链表+红黑树)

  1. HashSet底层是HashMap,第一次添加时,table数组扩容到16,临界值(threshold)是 16*加载因子(loadFactor)是0.75=12;
  2. 如果table数组使用到了临界值12,就会扩容到16*2=32,新的临界值就是32*0.75=24,以此类推。
  3. 在Java8中,如果一条链表的元素个数到达TREEIFY_THRESHOLD(默认是8)并且table的大小 >= MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树),否则仍然采用数组扩容机制。

Set接口实现类–LinkedHashSet

  1. LinkedHashSet是HashSet 的子类。

  2. LinkedHashSet 底层是一个LinkedHashMap,底层维护了一个数组+双链表

  3. LinkedHashSet根据元素的hashCode值决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

  4. LinkedHashSet不允许添加重复元素。

    Map接口和常用方法:(JDK8 以后的Map接口)

  5. Map与Collection并列存在,用于保存具有映射关系的数据:Key-Value(双列元素)

  6. Map中的key和value可以是任何引用类型的数据,会封装到HashMao$Node对象中。

  7. Map中的key不允许重复 ,原因和HashSet一样,Map中的值可以重复。

  8. Map的key可以为null,value也可以为null,注key为null只能有一个,value为null,可以为多个。

  9. 常用String类作为Map的key。

  10. Key和Value之间存在单向的一对一关系,即通过指定的Key总能找到对应的Value。

  11. Map存放数据的key-value,一对k-v是存放在一个Node中的,因为Node实现了Entry接口,因此有时被称为一个Entry。

1、k-v最后是HashMap$Node node = newNode(hash,key,value,null)

2、k-v为了方便程序员的遍历,还会创建EntrySet,该集合存放的元素类型Entry,而一个Entry对象就有k, v,EntrySet<Entry<K,V>>即:transient Set<Map. Entry<K,V>>entrySet;

3、entrySet中,定义类型是Map.Entry,但是实际上存放的还是HashMap$Node

//这是因为static class Node<K,V> implements Map.Entry<K,V>

4、当把HashMap$Node 对象存放到 entrySet 就方便遍历,因为Map.Entry提供重要方法 //K getKey(); V getValue();

Map接口常用的方法: put //添加 、remove//根据建删除映射关系、get//根据键获取值、size//获取元素个数 、isEmpty //判断个数是否为0、clear //清除 、containsKey//查找键是否存在。

HashMap的遍历方式:

  //一、通过Key取出对应的Value
        Set keyset = map.keySet();  //1、先取出所有的Key
        for (Object key : keyset) {//增强for
            System.out.println(key+""+map.get(key));
        }
        //2、迭代器
        Iterator iterator = keyset.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key+""+map.get(key));
        }
        //二、通过使用所有的Collection使用遍历方法
        //1、把所有的value取出
        Collection values = map.values();
        for (Object value : values) {
            System.out.println(value);
        }
        //2、迭代器
         Iterator iterator1 =values.iterator();
        while (iterator1.hasNext()) {
            Object value =  iterator1.next();
            System.out.println(value);
        }
        //三、通过EntrySet来获取 K - V
        Set entrySet = map.entrySet();//EntrySet<Map.Entry<K,V>>
        //1、增强For
        for (Object emtry : entrySet) {
            //将entry 转换成 Map.Entry
        Map.Entry m = (Map.Entry) emtry;
            System.out.println(m.getKey()+" -"+m.getValue());
        }
        //2、迭代器
        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()) {
            Object entry = iterator2.next();
            System.out.println(entry.getClass());//HashMap$Node -实现-> Map.Entry(getKey,getValue)
            //向下转型
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey()+"  "+m.getValue());
        }

​ HashMap小结:

  1. Map接口的常用实现类:HashMap、Hashtable 和Properties
  2. HashMap是Map 接口使用频率最高的实现类。
  3. HashMap是以key-val 对的方式来存储数据[Entry]
  4. key 不能重复,但是是值可以重复,允许使用null键和null值
  5. 如果添加相同的key,则会覆盖原来的key-val,等同于修改(key不会替换,val会替换)
  6. 与HashSet一样,不能保证映射的顺序,因此底层是以hash表的方式存储的。(jdk8的hashMap 底层 数组+链表+红黑树)
  7. HashMap没有实现同步,因此线程是不安全的。方法没有做同步互斥的操作,没有synchronized。

HashTable的基本介绍:

  1. 存放的元素是键值对:即 K-V
  2. hashtable的键和值都不能为null,否则会抛出NullPointerException
  3. hashTable使用方法基本与HashMap一样
  4. hashTable是线程安全的(synchronzied),hashMap是线程不安全的。

Hashtable的底层:

  1. 底层有数组Hashtable$Entry[] 初始化大小为11
  2. threshold 8 = 11 * 0.15
  3. 扩容:按照自己的扩容机制进行即可。当if(count >= threshold )满足时,就进行扩容 按照: int newCapacity = (oldCapacity <<1 )+ 1 ;的大小扩容。
线程安全效率允许null键null值
HashMap不安全可以
Hashtable安全不可以

​ Map接口实现类----Properties

  1. Properties类继承自Hashtable类并且实现Map接口,也是使用一种键值对的形式保存数据。使用特点和Hashtable类似
  2. Properties还可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改。
  3. xxx.properties 文件通常作为配置文件。

在开发中,选择什么集合实现类,主要取决于业务操作,然后根据集合实现类特性进行选择,分析如下:

  1. 先判断存储类型(一组对象[单例]或一组键值对[双列])

  2. 一组对象[单例]:Collection接口

    ​ 允许重复:List

    ​ 增删多: LinkedList[底层维护了一个双向链表]

    ​ 改查多:ArrayList[底层维护Object类型的可变数组]

    ​ 不允许重复:

    ​ 无序:HashSet [底层时HashMap,维护了一个哈希表即(数组+链表+红黑树)]

    ​ 排序:TreeSet

    ​ 插入和取出顺序一致:LinkedHashSet,维护数组+双向链表

  3. 一组键值对[双链表]:Map

    ​ 键无序: HashMap[底层是:哈希表 jdk7:数组+链表,jdk8:数组+链表+红黑树]

    ​ 键排序:TreeMap

    ​ 键插入和取出顺序一致:LinkedHashMap

    ​ 读取文件: Properties

//当使用无参构造器,创建TreeSet时,仍然时无序的。
		TreeSet treeSet =new TreeSet();
//使用TreeSet提供的一个构造器,可以传入一个比较器(匿名内部类)并致指定排序规则
	TreeSet treeSet = new TreeSet(new Comparator(){
        @Override
        public int compare(Object o1 , Object o2){
            //下面 调用String 的compareTo 方法进行字符串大小比较
            return ((String)o1).compareTo((String)o2);
        }
    });

Collection工具类:

  1. Collection是一个操作Set、List和Map等集合的工具类。
  2. Collections中提供了一系列静态方法对集合元素进行排序、查询和修改等操作。
  3. reverse(List):反转List中元素 shuffle(List):对List元素随机排序 sort(List) :根据元素的自然顺序对指定的List集合元素按升序排序 sort(List,Comparator):根据指定的Comparator 产生的顺序对List集合进行排序
  4. swap(List,int,int)将指定list集合中的i处元素和 j 处元素进行交换。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你的问题是如何在Java中定义一个商品类,并将其添加到ArrayList集合中。 首先,我们需要定义一个商品类,可以包含商品的名称、价格、描述等属性。以下是一个简单的商品类的示例: ``` public class Product { private String name; private double price; private String description; public Product(String name, double price, String description) { this.name = name; this.price = price; this.description = description; } public String getName() { return name; } public double getPrice() { return price; } public String getDescription() { return description; } } ``` 上面的代码定义了一个Product类,它有三个属性:name、price、description,以及一个构造函数和三个getter方法分别用于获取属性值。 接下来,我们可以创建一个ArrayList集合,并将商品对象添加到集合中。示例如下: ``` import java.util.ArrayList; public class Main { public static void main(String[] args) { // 创建一个商品列表 ArrayList<Product> productList = new ArrayList<>(); // 创建一些商品对象并添加到列表中 Product product1 = new Product("iPhone 12", 7999.00, "最新款苹果手机"); Product product2 = new Product("华为Mate 40", 5999.00, "华为旗舰手机"); productList.add(product1); productList.add(product2); // 遍历商品列表并输出商品信息 for (Product product : productList) { System.out.println("商品名称:" + product.getName()); System.out.println("商品价格:" + product.getPrice()); System.out.println("商品描述:" + product.getDescription()); } } } ``` 上面的代码创建了一个商品列表productList,并向其中添加了两个商品对象product1和product2。然后,使用for-each循环遍历商品列表,并输出每个商品的名称、价格和描述信息。 希望这个示例能回答你的问题!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值