Java--List的使用

1.泛型类的使用
1)看到<>就是泛型
2)
在这里插入图片描述
3)泛型背后的机制是作用在编译器间的
4)运行期间没有泛型的概念,统统认为是Object类型的引用(有一定的歧义)

2.包装类
int–》Interger
char–》Character
1)装箱(boxing)和拆箱(unboxing)
2)java提供自动装箱和拆箱
3)
在这里插入图片描述
在这里插入图片描述
关于List:支持实例化的只有两个类 ArrayList、LinkedList
在这里插入图片描述
3.应用–扑克牌
1)买一副牌(buyDeck):按花色A-K
2)洗牌(shuffle)
3)玩游戏–三个人、每人总共5张牌、按顺序发牌(send)
4)♠2在谁手中谁就输了(play)

注意
1)在paly方法中,不能直接card==hands.get(i).get(j) //是否指向同一张牌
2)java中进行对象值语义相等判断,不能直接比较引用是否相等,应覆写Object.equals方法
3)Node p; Node q; p == q; //是错误的
4)在equals方法中,不能直接this.value == obj.value; //因为obj不能.val,需要向下转型才可以取val
5)清楚泛型定义及使用
在这里插入图片描述

public class Card {
    public int value;
    public String color;

    public Card(int value, String color) {
        this.value = value;
        this.color = color;
    }

    @Override
    public String toString() { //覆写toString方法
        String v;
        if (value == 1) { //1--A 美观
            v = "A";
        } else {
            v = String.valueOf(value);
        }
        return String.format("[%s %s]", color, v);
    }

    @Override
    public boolean equals(Object obj) {//覆写equals方法
        // this 是 o 是否语义相等
        if (obj == null) {
            return false;
        }

        if (!(obj instanceof Card)) {//判断obj是不是Card类的对象
            return false;
        }

        if (obj == this) {
            return true;
        }

        // this.value == obj.value;
        // 需要向下转型 
        Card o = (Card)obj;
        return value == o.value && color.equals(o.color); //不能直接color == o.color
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class CardGame {
    private static final String[] COLORS = {
            "♠", "♥", "♦", "♣"
    };

    private static List<Card> buyDeck() {
        List<Card> deck = new ArrayList<>(52); //52是容量 
        //如果此时deck.get(0); 下标错误
        for (int i = 0; i < 4; i++) {
            String color = COLORS[i];
            for (int j = 1; j <= 13; j++) {
                int value = j;

                Card card = new Card(value, color);
                deck.add(card);
            }
        }
        return deck;
    }

    private static void shuffle(List<Card> deck) {
        Random random = new Random(20190916);  //随机种子相同 生成随机数相同
        for (int i = deck.size() - 1; i > 0; i--) {
            int r = random.nextInt(i); //[0,i) 生成0-i随机数
            swap(deck, i, r);
        }
    }

    private static void swap(List<Card> deck, int i, int j) {
        Card t = deck.get(i);
        deck.set(i, deck.get(j));
        deck.set(j, t);
    }

    public static void main(String[] args) {
        List<Card> deck = buyDeck();
        System.out.println("=============布牌=============");
        System.out.println(deck);
        shuffle(deck);
        System.out.println("=============洗牌=============");
        System.out.println(deck);
        List<List<Card>> hands = new ArrayList<>(); //玩家手里的牌
        send(hands, deck, 3, 5); //发牌
        System.out.println("========玩家1手里的牌=========");
        System.out.println(hands.get(0));
        System.out.println("========玩家2手里的牌=========");
        System.out.println(hands.get(1));
        System.out.println("========玩家3手里的牌=========");
        System.out.println(hands.get(2));
        System.out.println("==========剩余的牌============");
        System.out.println(deck);

        play(hands);
    }

    private static void play(List<List<Card>> hands) {
        Card card = new Card(2, "♠"); //先定义一张♠2的card
        
        for (int i = 0; i < hands.size(); i++) {  //一个人一个人的判断
        
            if (hands.get(i).contains(card)) { // boolean contains(Object o) ---判断o是否在线性表中
                System.out.println("=========♠2在谁手里?=========");
                int player = i+1;
                System.out.println( "玩家"+player +" 输了");
                 return;
            }
        }
        
              /*
            for (int j = 0; j < hands.get(i).size(); j++) {
                // 错误的
                Card handCard = hands.get(i).get(j);
                if (card.equals(handCard)) {
                    System.out.println("%d 输了");
                    return;
                }
            }
             */
    }


    //发牌
    private static void send(List<List<Card>> hands, List<Card> deck, int numPerson, int numCard) {
        // 调用 get 之前一定要保证元素是存在的
        for (int k = 0; k < numPerson; k++) {
            hands.add(new ArrayList<>()); //首先把引用插入hands中
        }

        for (int i = 0; i < numCard; i++) {
            for (int j = 0; j < numPerson; j++) {
                // 抓牌
                Card card = deck.remove(0); //删除玩家取走的牌--头删  (每次都发第0张牌)
                hands.get(j).add(card); 
            }
        }
    }
}

在这里插入图片描述
4.覆写equals方法
凡是需要用到引用的相等语义比较,必须调用equals方法
凡是自定义类,会被调用equals方法,就必须覆写
eg:List.contains//内部会调用元素类型的equals

1)如果是null,返回false
2)如果不是一个类型,返回false
3)根据类的定义来比较
注意:
1)如果不覆写,Object.equals默认的行为是:this == o;
2)p == q //判断p和q是否指向同一对象
p.equals(q) //判断p指向的对象和q指向的对象是否(语义)相等
3)eg:p != q但p和q语义相等
在这里插入图片描述
5.覆写equals实例
在这里插入图片描述
1)eg1:

public class Article {
    String title;
    String author;
    String content;
    String publishedAt;

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (!(obj instanceof Article)) {
            return false;
        }

        if (obj == this) {
            return true;
        }

        Article a = (Article)obj;
        if (!title.equals(a.title)) {
            return false;
        }

        if (!author.equals(a.author)) {
            return false;
        }

        if (!content.equals(a.content)) {
            return false;
        }

        return publishedAt.equals(a.publishedAt);
    }
}

2)eg2:

public class Student {
    public String sn;
    public String name;
    public int age;
    public int gender;

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (!(obj instanceof Student)) {
            return false;
        }

        if (this == obj) {
            return true;
        }

        return sn.equals(((Student) obj).sn); //学号可代表一个人
    }
}

6.杨辉三角
方法1:
1)创建一个 List<List> list = new ArrayList<>(); //存放最终杨辉三角数据
2)放入nums(eg:nums=5)个List // [ [],[],[],[],[] ]
3)全部填入1
4)修改需要修改的数值
需要修改行的所属下标:[2,numRows)
需要修改列的所属下标:[1,i)

方法2:
1)List<List> list
2)循环numRows次,每次new ArrayList<>() innerList;然后插入 list.add(innerList);
第一行:innerList.add(1); 第二行:innerList.add(1); innerList.add(1);
第三行:innerList.add(1); ……中间计算…… innerList.add(1);、
第n行:……

方法3:直接全部插入

import java.util.ArrayList;
import java.util.List;

public class PascalsTriangle {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> list = new ArrayList<>(); //存放最终杨辉三角数据
        for (int i = 0; i < numRows; i++) {
            list.add(new ArrayList<>());    // [  [],[],[],[],[]  ]
        }
        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j <= i; j++) {
                list.get(i).add(1);  //全部填入1
            }
        }
        for (int i = 2; i < numRows; i++) { //修改杨辉三角中不是1的地方
            for (int j = 1; j < i; j++) {
                int a = list.get(i - 1).get(j - 1);
                int b = list.get(i - 1).get(j);
                list.get(i).set(j, a + b);
            }
        }
        return list;
    }

    public List<List<Integer>> generate2(int numRows) {
        List<List<Integer>> list = new ArrayList<>();
        list.add(new ArrayList<>());
        // 第一行
        list.get(0).add(1);
        // 第二行
        list.add(new ArrayList<>());
        list.get(1).add(1);
        list.get(1).add(1);
        for (int i = 2; i < numRows; i++) {
            list.add(new ArrayList<>());
            list.get(i).add(1);
            //中间计算
            for (int j = 1; j < i; j++) {
                int a = list.get(i - 1).get(j - 1);
                int b = list.get(i - 1).get(j);
                list.get(i).add(a + b); // 这里不能调用 set(下标问题)
            }
            
            list.get(i).add(1);
        }
        return list;
    }

    public List<List<Integer>> generate3(int numRows) {
        /*
        int[][] result = {
                {1},
                {1,1},
                {1,2,1},
                {1,3,3,1},
                {1,4,6,4,1},
                {1,5,10,10,5,1}
        };
        */
        List<List<Integer>> list = new ArrayList<>();
        list.add(new ArrayList<>());
        // 第一行
        list.get(0).add(1);
        // 第二行
        list.add(new ArrayList<>());
        list.get(1).add(1);
        list.get(1).add(1);
        // 第三行
        list.add(new ArrayList<>());
        list.get(2).add(1);
        list.get(2).add(2);
        list.get(2).add(1);
        // 第四行
        list.add(new ArrayList<>());
        list.get(3).add(1);
        list.get(3).add(3);
        list.get(3).add(3);
        list.get(3).add(1);
        // 第五行
        list.add(new ArrayList<>());
        list.get(4).add(1);
        list.get(4).add(4);
        list.get(4).add(6);
        list.get(4).add(4);
        list.get(4).add(1);

        if (numRows == 5) {
            return list;
        }

        if (numRows < 5) {
            list.subList(0, numRows);
        }

        // 剩余部分用上述办法继续计算
        return null;
    }

    public static void main(String[] args) {
        System.out.println("================方法1=================");
        System.out.println(new PascalsTriangle().generate(5));
        System.out.println("================方法2=================");
        System.out.println(new PascalsTriangle().generate2(5));
        System.out.println("================方法3=================");
        System.out.println(new PascalsTriangle().generate3(5));
    }
}

在这里插入图片描述

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值