第11章 持有对象(容器 java编程思想)

手把手用瑞萨E1仿真器调试RH850 CAN通信:从报文收发到底层寄存器监控 本文详细介绍了使用瑞萨E1仿真器调试RH850 CAN通信的全过程,包括硬件连接、CS+开发环境配置、CAN控制器寄存器解析以及双通道网关实战开发。通过实战案例和错误诊断技巧,帮助开发者快速掌握RH850F1L的RS-CAN控制器应用,提升车载网络开发效率。 阅读详情

11.1 泛型和安全的容器

可以把ArrayList当做“可以自动扩充自身尺寸的数组”来看待。使用ArrayList相当简单。创建一个实例,用add()来插入对象,然后用get()
来访问这些对象,此时需要使用索引,就像数组一样,需要方括号。ArrayList还有一个size()方法,使你可以知道有多少元素添加了进来。

//: holding/ApplesAndOrangesWithGenerics.java
import java.util.*;

public class ApplesAndOrangesWithGenerics {
  public static void main(String[] args) {
    ArrayList<Apple> apples = new ArrayList<Apple>();
    for(int i = 0; i < 3; i++)
      apples.add(new Apple());
    // Compile-time error:
    // apples.add(new Orange());
    for(int i = 0; i < apples.size(); i++)
      System.out.println(apples.get(i).id());
    // Using foreach:
    for(Apple c : apples)
      System.out.println(c.id());
  }
} /* Output:
0
1
2
0
1
2
*///:~

当ArrayList没有添加任何参数时,你可以添加任意对象进入其中,而不会报错,但是取出对象时,你得到的只是Object对象,必须将其转型为Apple,通过使用泛型,就可以在编译期防止将错误的类型的对象错误的放到容器中。

11.2 基本概念

1)Collection 。一个独立元素的序列。List必须按照插入的顺序保存元素,而Set不能有重复的元素。Queue按照排队的顺序来确定对象产生的顺序(通常与他被插入的对象的顺序相同)
2)Map 一组成对的“键值对”对象,允许你使用键来查找值,ArrayList允许你使用数字来查找值,因此在某种意义上来讲,它将数字与对象关联在了一起,你可以使用键对象来查找对象,就像在字典中使用单词来定义一样,Map是强大的编程工具。

//: holding/SimpleCollection.java
import java.util.*;

public class SimpleCollection {
  public static void main(String[] args) {
    Collection<Integer> c = new ArrayList<Integer>();
    for(int i = 0; i < 10; i++)
      c.add(i); // Autoboxing
    for(Integer i : c)
      System.out.print(i + ", ");
  }
} /* Output:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
*///:~

11.3 添加一组元素

ArrayList()方法接受一个数组或四一个用逗号分隔·的元素列表(使用可变参数),并将其转换为一个List对象,Collection.addAll()接受一个Collection对象,以及一个数组活用逗号分隔的列表,并将元素添加到Collection中,下面的事例展示了这两个方法,以及更加传统的addAll方法。

//: holding/AddingGroups.java
// Adding groups of elements to Collection objects.
import java.util.*;

public class AddingGroups {
  public static void main(String[] args) {
    Collection<Integer> collection =
      new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
    Integer[] moreInts = { 6, 7, 8, 9, 10 };
    collection.addAll(Arrays.asList(moreInts));
    // Runs significantly faster, but you can't
    // construct a Collection this way:
    Collections.addAll(collection, 11, 12, 13, 14, 15);
    Collections.addAll(collection, moreInts);
    // Produces a list "backed by" an array:
    List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);
    list.set(1, 99); // OK -- modify an element
    // list.add(21); // Runtime error because the
                     // underlying array cannot be resized.
  }
} ///:~

调用Collection.addAll这种方式很方便,因此它是首选方式。

11.4 容器的打印

必须使用ArrayList.toString()来产生数组的课打印表示。

//: holding/PrintingContainers.java
// Containers print themselves automatically.
import java.util.*;
import static net.mindview.util.Print.*;

public class PrintingContainers {
  static Collection fill(Collection<String> collection) {
    collection.add("rat");
    collection.add("cat");
    collection.add("dog");
    collection.add("dog");
    return collection;
  }
  static Map fill(Map<String,String> map) {
    map.put("rat", "Fuzzy");
    map.put("cat", "Rags");
    map.put("dog", "Bosco");
    map.put("dog", "Spot");
    return map;
  }	
  public static void main(String[] args) {
    print(fill(new ArrayList<String>()));
    print(fill(new LinkedList<String>()));
    print(fill(new HashSet<String>()));
    print(fill(new TreeSet<String>()));
    print(fill(new LinkedHashSet<String>()));
    print(fill(new HashMap<String,String>()));
    print(fill(new TreeMap<String,String>()));
    print(fill(new LinkedHashMap<String,String>()));
  }
} /* Output:
[rat, cat, dog, dog]
[rat, cat, dog, dog]
[dog, cat, rat]
[cat, dog, rat]
[rat, cat, dog]
{dog=Spot, cat=Rags, rat=Fuzzy}
{cat=Rags, dog=Spot, rat=Fuzzy}
{rat=Fuzzy, cat=Rags, dog=Spot}
*///:~

ArrayList和LinkedList都是List类型,他们都按照顺序来保存对象,两者不同之处不仅在于执行某些类型操作时的性能,而且LinkedList包含的操作要多于ArrayList。
HashSet,TreeSet,LinkedHashSet都是Set类型,HashSet是最快的获取元素的方式,如果顺序很重要,使用TreeSet,他使用的按照比较结果的升序保存对象,LinkedHashSet按照添加的顺序来保存对象。

11.5 List

下面的例子介绍了一些List的操作。

//: holding/ListFeatures.java
import typeinfo.pets.*;
import java.util.*;
import static net.mindview.util.Print.*;

public class ListFeatures {
  public static void main(String[] args) {
    Random rand = new Random(47);
    List<Pet> pets = Pets.arrayList(7);
    print("1: " + pets);
    Hamster h = new Hamster();
    pets.add(h); // Automatically resizes
    print("2: " + pets);
    print("3: " + pets.contains(h));
    pets.remove(h); // Remove by object
    Pet p = pets.get(2);
    print("4: " +  p + " " + pets.indexOf(p));
    Pet cymric = new Cymric();
    print("5: " + pets.indexOf(cymric));
    print("6: " + pets.remove(cymric));
    // Must be the exact object:
    print("7: " + pets.remove(p));
    print("8: " + pets);
    pets.add(3, new Mouse()); // Insert at an index
    print("9: " + pets);
    List<Pet> sub = pets.subList(1, 4);
    print("subList: " + sub);
    print("10: " + pets.containsAll(sub));
    Collections.sort(sub); // In-place sort
    print("sorted subList: " + sub);
    // Order is not important in containsAll():
    print("11: " + pets.containsAll(sub));
    Collections.shuffle(sub, rand); // Mix it up
    print("shuffled subList: " + sub);
    print("12: " + pets.containsAll(sub));
    List<Pet> copy = new ArrayList<Pet>(pets);
    sub = Arrays.asList(pets.get(1), pets.get(4));
    print("sub: " + sub);
    copy.retainAll(sub);
    print("13: " + copy);
    copy = new ArrayList<Pet>(pets); // Get a fresh copy
    copy.remove(2); // Remove by index
    print("14: " + copy);
    copy.removeAll(sub); // Only removes exact objects
    print("15: " + copy);
    copy.set(1, new Mouse()); // Replace an element
    print("16: " + copy);
    copy.addAll(2, sub); // Insert a list in the middle
    print("17: " + copy);
    print("18: " + pets.isEmpty());
    pets.clear(); // Remove all elements
    print("19: " + pets);
    print("20: " + pets.isEmpty());
    pets.addAll(Pets.arrayList(4));
    print("21: " + pets);
    Object[] o = pets.toArray();
    print("22: " + o[3]);
    Pet[] pa = pets.toArray(new Pet[0]);
    print("23: " + pa[3].id());
  }
} /* Output:
1: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug]
2: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Hamster]
3: true
4: Cymric 2
5: -1
6: false
7: true
8: [Rat, Manx, Mutt, Pug, Cymric, Pug]
9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug]
subList: [Manx, Mutt, Mouse]
10: true
sorted subList: [Manx, Mouse, Mutt]
11: true
shuffled subList: [Mouse, Manx, Mutt]
12: true
sub: [Mouse, Pug]
13: [Mouse, Pug]
14: [Rat, Mouse, Mutt, Pug, Cymric, Pug]
15: [Rat, Mutt, Cymric, Pug]
16: [Rat, Mouse, Cymric, Pug]
17: [Rat, Mouse, Mouse, Pug, Cymric, Pug]
18: false
19: []
20: true
21: [Manx, Cymric, Rat, EgyptianMau]
22: EgyptianMau
23: 14
*///:~

你可以用contains()方法来确定某个对象是否在列表中,如果你想移除一个对象,则可以将这个对象的引用传递给remove()方法。 同样如果你有一个对象的引用,则可以使用indexOf()来发现该对象在List中所处位置的索引编号。
subList()方法允许你很容易的从较大的列表中创建出一个片段,而将这个结果传递个较大的列表的containsAll(),很自然的会得到true。
retainAll()是一种有效的交集操作,他保留了同时在copy中与sub中的元素。
可以使用toArray()方法将任意的Collection转换为一个数组,如果参数数组太小,存放不下List中的所有元素,toArray()将创建一个具有合适尺寸的数组。

11.6 迭代器

迭代器是一个对象,它的工作是遍历并选择序列中的对象。而客户端程序员不必关心该序列的底层结构,创建迭代器的代价很小,因此它也被称为轻量级对象,java的Iterator只能单向移动,这个Iterator只能用来。
1)使用方法Iterator()要求容器返回一个Iterator。Iterator将准备好返回第一个元素。
2)使用next()获得序列中的下一个对象。
3)使用hasNext()检查序列中是否还有元素。
4)使用remove()将迭代器新返回的元素删除。

//: holding/SimpleIteration.java
import typeinfo.pets.*;
import java.util.*;

public class SimpleIteration {
  public static void main(String[] args) {
    List<Pet> pets = Pets.arrayList(12);
    Iterator<Pet> it = pets.iterator();
    while(it.hasNext()) {
      Pet p = it.next();
      System.out.print(p.id() + ":" + p + " ");
    }
    System.out.println();
    // A simpler approach, when possible:
    for(Pet p : pets)
      System.out.print(p.id() + ":" + p + " ");
    System.out.println();	
    // An Iterator can also remove elements:
    it = pets.iterator();
    for(int i = 0; i < 6; i++) {
      it.next();
      it.remove();
    }
    System.out.println(pets);
  }
} /* Output:
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
[Pug, Manx, Cymric, Rat, EgyptianMau, Hamster]
*///:~

迭代器能够将遍历序列的操作与序列底层的结构分离,正由如此,我有时会说:迭代器统一了对容器的访问的方式。

//: holding/CrossContainerIteration.java
import typeinfo.pets.*;
import java.util.*;

public class CrossContainerIteration {
  public static void display(Iterator<Pet> it) {
    while(it.hasNext()) {
      Pet p = it.next();
      System.out.print(p.id() + ":" + p + " ");
    }
    System.out.println();
  }	
  public static void main(String[] args) {
    ArrayList<Pet> pets = Pets.arrayList(8);
    LinkedList<Pet> petsLL = new LinkedList<Pet>(pets);
    HashSet<Pet> petsHS = new HashSet<Pet>(pets);
    TreeSet<Pet> petsTS = new TreeSet<Pet>(pets);
    display(pets.iterator());
    display(petsLL.iterator());
    display(petsHS.iterator());
    display(petsTS.iterator());
  }
} /* Output:
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
4:Pug 6:Pug 3:Mutt 1:Manx 5:Cymric 7:Manx 2:Cymric 0:Rat
5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug 0:Rat
*///:~

11.6.1 ListIterator
ListIterator是一个更加强大的Iterator的子类型,它只能用于各种List类的访问,但是ListIterator可以双向移动,你可以使用ListIterator(n)创建一个一开始索引为n的元素出的ListIterator。n指的是第几个元素,而不是元素的地址。
你也可以用迭代器来进行add(),set(),remove()等操作

//: holding/ListIteration.java
import typeinfo.pets.*;
import java.util.*;

public class ListIteration {
  public static void main(String[] args) {
    List<Pet> pets = Pets.arrayList(8);
    ListIterator<Pet> it = pets.listIterator();
    while(it.hasNext())
      System.out.print(it.next() + ", " + it.nextIndex() +
        ", " + it.previousIndex() + "; ");
    System.out.println();
    // Backwards:
    while(it.hasPrevious())
      System.out.print(it.previous().id() + " ");
    System.out.println();
    System.out.println(pets);	
    it = pets.listIterator(3);
    while(it.hasNext()) {
      it.next();
      it.set(Pets.randomPet());
    }
    System.out.println(pets);
  }
} /* Output:
Rat, 1, 0; Manx, 2, 1; Cymric, 3, 2; Mutt, 4, 3; Pug, 5, 4; Cymric, 6, 5; Pug, 7, 6; Manx, 8, 7;
7 6 5 4 3 2 1 0
[Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Manx]
[Rat, Manx, Cymric, Cymric, Rat, EgyptianMau, Hamster, EgyptianMau]
*///:~

11.7 LinkedList

getFirst()和element()完全一样,他们都返回列表的头部,而不移除他,如果List为空,则抛出NoSuchElementException错误。peek()方法与这两个方式只是稍有差异,返回一个null。
remove()与removeFirst()也是完全一样的,他们移除这个表的头,而在表为空的时候,则抛出NoSuchElementException错误,poll()在列表为空的时候返回null。
addFirst()与add()和addLast()相同,都是在表中插入元素。
removeLast()移除并返回列表的最后一个元素。

//: holding/LinkedListFeatures.java
import typeinfo.pets.*;
import java.util.*;
import static net.mindview.util.Print.*;

public class LinkedListFeatures {
  public static void main(String[] args) {
    LinkedList<Pet> pets =
      new LinkedList<Pet>(Pets.arrayList(5));
    print(pets);
    // Identical:
    print("pets.getFirst(): " + pets.getFirst());
    print("pets.element(): " + pets.element());
    // Only differs in empty-list behavior:
    print("pets.peek(): " + pets.peek());
    // Identical; remove and return the first element:
    print("pets.remove(): " + pets.remove());
    print("pets.removeFirst(): " + pets.removeFirst());
    // Only differs in empty-list behavior:
    print("pets.poll(): " + pets.poll());
    print(pets);
    pets.addFirst(new Rat());
    print("After addFirst(): " + pets);
    pets.offer(Pets.randomPet());
    print("After offer(): " + pets);
    pets.add(Pets.randomPet());
    print("After add(): " + pets);
    pets.addLast(new Hamster());
    print("After addLast(): " + pets);
    print("pets.removeLast(): " + pets.removeLast());
  }
} /* Output:
[Rat, Manx, Cymric, Mutt, Pug]
pets.getFirst(): Rat
pets.element(): Rat
pets.peek(): Rat
pets.remove(): Rat
pets.removeFirst(): Manx
pets.poll(): Cymric
[Mutt, Pug]
After addFirst(): [Rat, Mutt, Pug]
After offer(): [Rat, Mutt, Pug, Cymric]
After add(): [Rat, Mutt, Pug, Cymric, Pug]
After addLast(): [Rat, Mutt, Pug, Cymric, Pug, Hamster]
pets.removeLast(): Hamster
*///:~

11.9 Set

Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像前面两个不同的Set,实际上Set就是Collection,只是行为不同。
Set不保存重复的元素,Set中最常用的是测试归属性,你可以很容易的查询到某个对象是否在某个Set中,因此,查找就成了Set中最重要的操作,所以通常都会选择一个HashSet的实现,它专门对快速查找进行了优化。

//: holding/SetOfInteger.java
import java.util.*;

public class SetOfInteger {
  public static void main(String[] args) {
    Random rand = new Random(47);
    Set<Integer> intset = new HashSet<Integer>();
    for(int i = 0; i < 10000; i++)
      intset.add(rand.nextInt(30));
    System.out.println(intset);
  }
} /* Output:
[15, 8, 23, 16, 7, 22, 9, 21, 6, 1, 29, 14, 24, 4, 19, 26, 11, 18, 3, 12, 27, 17, 2, 13, 28, 20, 25, 10, 5, 0]
*///:~

你可以注意到,输出的顺序没有任何规律可言,HashSet所维护的顺序与TreeSet或LinkedHashSet都不同,因为他们的实现具有不同的元素存储方式。如果想要对结果进行排序,一种方式是用TreeSet来代替HashSet:

//: holding/SortedSetOfInteger.java
import java.util.*;

public class SortedSetOfInteger {
  public static void main(String[] args) {
    Random rand = new Random(47);
    SortedSet<Integer> intset = new TreeSet<Integer>();
    for(int i = 0; i < 10000; i++)
      intset.add(rand.nextInt(30));
    System.out.println(intset);
  }
} /* Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
*///:~

11.10 Map

将对象映射到其他对象的能力是一种解决编程问题的杀手锏,例如要计算Random产生的各种不同范围的数字进行计数,Map可以很容易的解决问题。在本例中,键是由Random产生的数字,而值是该数字出现的次数;

//: holding/Statistics.java
// Simple demonstration of HashMap.
import java.util.*;

public class Statistics {
  public static void main(String[] args) {
    Random rand = new Random(47);
    Map<Integer,Integer> m =
      new HashMap<Integer,Integer>();
    for(int i = 0; i < 10000; i++) {
      // Produce a number between 0 and 20:
      int r = rand.nextInt(20);
      Integer freq = m.get(r);
      m.put(r, freq == null ? 1 : freq + 1);
    }
    System.out.println(m);
  }
} /* Output:
{15=497, 4=481, 19=464, 8=468, 11=531, 16=533, 18=478, 3=508, 7=471, 12=521, 17=509, 2=489, 13=506, 9=549, 6=519, 1=502, 14=477, 10=513, 5=503, 0=481}
*///:~

下面的事例允许你使用一个String描述来查找Pet,它还展示了你可以使用怎样的方法使用containsKey(),和containValue()来测试一个Map(),以便查看他是否包含某个键或者某个类。

//: holding/PetMap.java
import typeinfo.pets.*;
import java.util.*;
import static net.mindview.util.Print.*;

public class PetMap {
  public static void main(String[] args) {
    Map<String,Pet> petMap = new HashMap<String,Pet>();
    petMap.put("My Cat", new Cat("Molly"));
    petMap.put("My Dog", new Dog("Ginger"));
    petMap.put("My Hamster", new Hamster("Bosco"));
    print(petMap);
    Pet dog = petMap.get("My Dog");
    print(dog);
    print(petMap.containsKey("My Dog"));
    print(petMap.containsValue(dog));
  }
} /* Output:
{My Cat=Cat Molly, My Hamster=Hamster Bosco, My Dog=Dog Ginger}
Dog Ginger
true
true
*///:~

Map和其他Collection一样,可以扩展,Map的值可以是其他容器,使得我们可以很轻松生成强大的数据结构。
例如: Map<Person , List>;

11.11 Queue

LinkList提供了方法以支持队列的对象,并且它实现了Queue接口,因此LinkList可以作为Queue的一种实现,通过将LinkList向上转型为Queue。

//: holding/QueueDemo.java
// Upcasting to a Queue from a LinkedList.
import java.util.*;

public class QueueDemo {
  public static void printQ(Queue queue) {
    while(queue.peek() != null)
      System.out.print(queue.remove() + " ");
    System.out.println();
  }
  public static void main(String[] args) {
    Queue<Integer> queue = new LinkedList<Integer>();
    Random rand = new Random(47);
    for(int i = 0; i < 10; i++)
      queue.offer(rand.nextInt(i + 10));
    printQ(queue);
    Queue<Character> qc = new LinkedList<Character>();
    for(char c : "Brontosaurus".toCharArray())
      qc.offer(c);
    printQ(qc);
  }
} /* Output:
8 1 1 1 5 14 3 1 0 1
B r o n t o s a u r u s
*///:~

offer()方法是与Queue相关的方法之一,它在允许的情况下将一个元素插入队尾,或者返回false,peek()和element()都将在不移除的情况下返回队头,但是peek()在队列为空的时候返回null,而element()会抛出NoSuchElementException异常。poll()和remove()方法将移除并返回队头,但是poll()在队列为空时候返回null,而remove()会抛出NoSuchElementException()异常
Queue接口窄化了对LinkList的方法的访问权限,以使得只有恰当的方法才可以使用,因此,你能够访问的LinkList方法会变少。
11.11.1 PriorityQueue
当你在PriorityQueue上调用一个offer来插入一个对象是,这个对象会在队列中被排序,默认的排序将使用对象在队列中的自然顺序,但是你可以使用Comparator来修改这个顺序,PriorityQueue可以确保你在调用peek()poll()remove()方法时,获取的元素将是队列中优先级最高的元素。

//: holding/PriorityQueueDemo.java
import java.util.*;

public class PriorityQueueDemo {
  public static void main(String[] args) {
    PriorityQueue<Integer> priorityQueue =
      new PriorityQueue<Integer>();
    Random rand = new Random(47);
    for(int i = 0; i < 10; i++)
      priorityQueue.offer(rand.nextInt(i + 10));
    QueueDemo.printQ(priorityQueue);

    List<Integer> ints = Arrays.asList(25, 22, 20,
      18, 14, 9, 3, 1, 1, 2, 3, 9, 14, 18, 21, 23, 25);
    priorityQueue = new PriorityQueue<Integer>(ints);
    QueueDemo.printQ(priorityQueue);
    priorityQueue = new PriorityQueue<Integer>(
         Collections.reverseOrder());
    priorityQueue.addAll(ints);
    QueueDemo.printQ(priorityQueue);

    String fact = "EDUCATION SHOULD ESCHEW OBFUSCATION";
    List<String> strings = Arrays.asList(fact.split(""));
    PriorityQueue<String> stringPQ =
      new PriorityQueue<String>(strings);
    QueueDemo.printQ(stringPQ);
    stringPQ = new PriorityQueue<String>(
      strings.size(), Collections.reverseOrder());
    stringPQ.addAll(strings);
    QueueDemo.printQ(stringPQ);

    Set<Character> charSet = new HashSet<Character>();
    for(char c : fact.toCharArray())
      charSet.add(c); // Autoboxing
    PriorityQueue<Character> characterPQ =
      new PriorityQueue<Character>(charSet);
    QueueDemo.printQ(characterPQ);
  }
} /* Output:
0 1 1 1 1 1 3 5 8 14
1 1 2 3 3 9 9 14 14 18 18 20 21 22 23 25 25
25 25 23 22 21 20 18 18 14 14 9 9 3 3 2 1 1
       A A B C C C D D E E E F H H I I L N N O O O O S S S T T U U U W
W U U U T T S S S O O O O N N L I I H H F E E E D D C C C B A A
  A B C D E F H I L N O S T U W
*///:~

11.13 Foreach与迭代器

能够与Foreach工作是所有Collection对象的特性。之所以能够工作,是因为java SE5中加入了新的被称为Iterator的接口,该接口包含了一个能够产生Iterator的iterator()的方法,并且Iterator接口被Foreach用来在序列中移动,因此如果你创建了任何实现ITerator的类,都可以将它用于Foreach语句中:

//: holding/IterableClass.java
// Anything Iterable works with foreach.
import java.util.*;

public class IterableClass implements Iterable<String> {
  protected String[] words = ("And that is how " +
    "we know the Earth to be banana-shaped.").split(" ");
  public Iterator<String> iterator() {
    return new Iterator<String>() {
      private int index = 0;
      public boolean hasNext() {
        return index < words.length;
      }
      public String next() { return words[index++]; }
      public void remove() { // Not implemented
        throw new UnsupportedOperationException();
      }
    };
  }	
  public static void main(String[] args) {
    for(String s : new IterableClass())
      System.out.print(s + " ");
  }
} /* Output:
And that is how we know the Earth to be banana-shaped.
*///:~

华为自研 ERP、Oracle EBS 与 SAP 上线时系统配置思路设计差异深度分析 本文对比分析了华为自研ERP、Oracle EBS和SAP S/4HANA三大ERP系统在上线配置思路上的核心差异。从架构设计看,华为采用分布式微服务架构,SAP采用分层服务架构,Oracle采用集中式一体化架构;在模块配置上,华为以业务场景为导向,SAP基于行业模板,Oracle强调模块独立性;数据迁移方面,华为侧重业务规则清洗,SAP注重数据质量监控,Oracle依赖标准化工具;流程适配上,华为系统随流程调整,SAP在框架内优化,Oracle需定制开发;定制开发模式差异明显,华为采用插件化扩展,SAP使 阅读详情

相关推荐

基于陀螺仪航向反馈的轮式机器人PID直线控制

航向角控制是移动机器人实现稳定直线运动的基础技术,其本质是通过实时感知机体朝向偏差并动态调节驱动输出,以抵消机械不对称、轮径误差等固有扰动。该方法依托陀螺仪测量角速度并积分解算航向角,结合离散化PID算法生成补偿性PWM指令,在嵌入式平台(如STM32)上构建低延迟闭环。相比依赖编码器的速度闭环,它规避了轮径标定与安装偏心等误差源,显著提升低成本平台的工程鲁棒性与部署效率。典型应用场景包括教育机器人直线循迹、AGV基础导航模块开发及IMU-PID融合控制原型验证。

web39explorer的博客 1110

编写一个Java应用程序,产生20个50-100之内的整数,并输出这20个数并找出最大数及最小数输出。

(1)思路 引入Random类和Arrays类分别用于产生随机数和对数组的操作! (2)代码实现 package p2; import java.util.Random; import java.util.Arrays; public class R { public static void main(String[] args) { double number; double array[]=new double[20]; Random random = new Random();

ONE_one_plus的博客 1776

中文顶刊《会计研究》文本分析技术最新进展总结盘点

会计研究》是由中华人民共和国财政部主管、中国会计学会主办的国家一级学术期刊,为会计领域中文顶级期刊。随着大数据技术的日益成熟, 社交网络类文本 、上市公司披露类文本、媒体报道类文本、 其他类文本 、网络搜索数据、P2P 网络借贷文 本与分析师报告等文本数据逐渐成为财务会计的研究素材。

qq_52891550的博客 2891

《JAVA编程思想》的学习

今天第一次发表博客,也是因为我正在学习JAVA编程思想,想自己做个记录,也有个总结。 第十一章 持有对象  1.List 主要有两种类型:1.ArrayList和ArrayList。 ArrayList:它随机访问元素比较快,但是在List的中间插入和移除元素时较慢。 LinkedList:它通过随机访问元素比较慢,但是在List的中间进行插入和删除较慢。 List通过我自己的

qq_31170429的博客 367

库卡机器人负载设置和自动负载测算

1.1在专家或者以上的权限下—“投入运行”——“工具/基座标管理”—“工具/工件”—添加1.2根据当前的工具所在的tool选择指定工具号;若是没有建立tool需要先建立建立方法看1.3负载数据的填写质量:抓手自重+产品重量总和(需要小于额定负载值)X、Y、Z :总质量的重心位置(基于法兰盘中心的位置计算,如下图的X_FLANGE、Y_FLANGE、Z_FLANGE)【此数据可以根据仿真或者CAD数据得出】A、B、C:是总质量绕着法兰盘中心所安装的角度位置 【此数据可以根据仿真或者CAD数据得出】

weixin_43462131的博客 3102

ROS下UR+Realsense相机进行手眼标定

手眼标定主要是用来确定相机坐标系和机械臂坐标系之间的转换关系,从而实现后续的抓取等任务。

weixin_42157689的博客 7571

Java 容器类练习题(一)

题目1:创建一个名为Gerbil的类,该类拥有一个整数域gerbilNumber,通过构造器初始化gerbilNumber。创建方法hop()显示该对象的gerbilNumber,以及“is hopping.” 创建一个ArrayList,并将Gerbil对象添加到该List中。用get()方法遍历List中所有的Gerbil对象,并调用hop()方法。 解答1: import java....

weixin_30736301的博客 505

国科大学习资料--自然语言处理(宗成庆)-2019期末考试题

国科大学习资料–自然语言处理(宗成庆)-2019期末考试题 国科大学习资料–自然语言处理(宗成庆)-2019期末考试题 国科大学习资料–自然语言处理(宗成庆)-2019期末考试题

无名何许人的博客 2438

读书笔记:《JAVA编程思想(Thinking in Java)》第11章 持有对象(容器)

在写程序时并不知道将需要多少个对象,Java类库提供了一套完整的容器类来解决这个问题。最基本的类型是List、Set、Queue、Map。容器类都可以自动地调整自己的大小,可以将任意数量的对象放置到容器中。 泛型和类型安全的容器 在Java5之前的主要问题是编译器允许你向容器中插入不正确的类型。 import java.util.ArrayList; class Apple{ private s...

砥砺前行的博客 292

从数字后端角度谈谈occ电路(一)

摘要:本文介绍了芯片测试中OCC(On-Chip Clock Control)电路的设计与应用。随着工艺进步,芯片制造面临Stuck-at、Bridging和Delay等故障类型,需要不同时钟频率进行测试。OCC电路通过Clock Selection、Clock Chopping Control和Clock Gating三个模块,实现ATE时钟与PLL时钟的切换控制,支持慢速时钟检测Stuck-at故障和快速时钟检测Delay故障。文章详细解析了OCC电路结构及各模块功能,包括同步单元、移位寄存器等关键组件

芯冰乐 585

LightGBM之LGBMRegressor()参数详解以及调参

LightGBMLight Gradient Boosting Machine)是一种梯度提升框架,它使用决策树作为基学习器。LightGBM 可以说是在 XGBoost 上做的优化。LightGBM 为高效并行计算而生,它的 Light 体现在以下几个点上:更快的训练速度更低的内存使用支持单机多线程,多机并行计算,以及 GPU 训练能够处理大规模数据。

我走的每一步都算数 3747

《JAVA编程思想》学习笔记:第11章(持有对象)

目录Java编程思想(一)第1~4章:概述Java编程思想(二)第5章:初始化和清理Java编程思想(三)第6章:访问权限Java编程思想(四)第7章:复用类Java编程思想(五)第8章:多态Java编程思想(六)第9章:接口Java编程思想(七)第10章:内部类Java编程思想(八)第11章:持有对象Java编程思想(九)第12章:异常Java编程思想(十)第13章:字符串Java编程思想(十一...

caobaokang的专栏 3292

柔性电极材料新突破:清华团队实现0.1mV级脑信号采集精度

清华团队的 0.1mV 级柔性电极突破,不仅是材料科学与神经工程的跨界胜利,更标志着脑机接口从 “信号采集” 向 “神经交互” 的范式转变。当电极与脑组织实现 “柔性共生”,人类首次拥有了窥探大脑微观电活动的 “精密探头”,这既是神经疾病诊疗的里程碑,更是人机融合时代的新起点。随着技术标准化与产业生态的完善,这场始于实验室的 “柔性革命”,正加速向临床病房、智能工厂、消费电子等场景渗透,为脑机接口的大规模应用铺设 “柔性跑道”。:当柔性电极实现 “神经信号的无损捕捉”,如何平衡技术创新与伦理边界?

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 2943

《Java编程思想》读书笔记 —— 第11章 持有对象

前面的章节都更重视理论一些,”持有对象“这一章却有点不一样,感觉更重视的是应用,也就是让读者学会使用Java中容器类的使用方法。关于容器类更加深层次的内容,主要是在第17章”容器深入研究“中叙述。即使是这样,这章的篇幅还是比前面都长不少……希望能概括的不错吧。 持有对象,根据字面意思来理解,应该是如何保存对象的意思。当我们不知道会需要创建多少对象、需要很好地统一管理很多对象的时候,依靠创建命名的引...

banqinghe的博客 659

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Thinking in java 第11章 持有对象 笔记+习题

Thinking in java 第11章 持有对象 笔记+习题 学习目录 11.1 泛型和类型安全的容器 1. 当你制定了某个类型作为泛型参数时,你并不仅限于只能将该确切类型的对象放置到容器中。向上转型也可一样作用于泛型。 11.2 基本概念 1. Java容器被划分为两个概念: Collection:一个独立元素的序列,这些元素都服从一条或多条规则。 Map:一组成对的“键值对”对象,允许你使用键来查找值。 11.3 添加一元素 1. Arrays.asList()方法接收...

soyamilk233的博客 1477

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

《Java编程思想》阅读笔记之第11章-持有对象

第11章-持有对象 容器类的引入:Java需要有不同的方式来保存对象(或说是对象的引用)。 如数组可以保存一组对象或一组基本类型数据,也推荐使用,但是数组必需有固定的尺寸,但在实际的情况中,可能根本不知道需要多少个对象,所以数组尺寸固定就是一个局限了。 于是Java实用类库提供了一套完整的容器类来解决这个问题,包括List、Set、Queue和Map,容器类可以自动调整自己的尺寸,不需要担心容器的大小问题。 11.1 泛型和类型安全的容器 最基本最可靠的容器ArrayList可以被当作“可以自动扩

二木成林 386

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

《Java编程思想》读书笔记:第十一章 持有对象

在本例中,Apple和Orange都放置在了容器中,然后将它们取出。正常情况下,Java编译器会报告警告信息,因为这个示例没有使用泛型。在这里,我们使用Java SE5所特有的注解。

Mr_Kian的博客 876

Java编程思想笔记11——第11章:持有对象

11 持有对象 ​ 通常,程序总是根据运行时才知道某些条件去创建新的对象。 ​ 不需要事先定义好创建的数量,可以根据需要创建任意数量的对象。 ​ 数组则必须实现指定数量,所以有所约束。 ​ Java提供了容器类来解决这个问题,基本的类型是List、Set、Queue和Map。这些称之为集合类,且都是Collection类或Map类的子类。 ​ Set不能保存重复值。 Map允许将对象与其他对象关联起来。 ​ 这些容器不需要事先指定大小。 ​ 11.1 泛型和类型安全的容器 ​ 在JavaSE5之前,可以像容

qq_35556504的博客 216

《Java编程思想》第四版 摘抄笔记7 - 持有对象(容器)

①Map与数组和其他的Collection一样,可以很容易地扩展到多维,而我们只需要将其值设置为Map(这些Map的值可以是其他容器,甚至是其他Map)。有时栈也被称为叠加栈,因为最后“压入”栈的元素,第一个“弹出 ”栈。经常用来类比栈的事物是装有弹簧的储放器中的自主餐托盘,最后装入的托盘总是最先拿出 使用的。即从容器的一端放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。(5)迭代器是一个对象,它的工作是遍历并选择序列中的对象,而客户端程序员 不必知道或关心该序列底层的结构。

qq_44031124的博客 449

第11章 持有对象

数组将索引与对象联系起来,保存类型明确的对象,可以是多维的,数组一旦生成,容量就不能改变;Collection保存单一元素,Map保存相关联的键值对。可以自动调整大小,不能持有基本类型,但是可以自动包装;List将索引与对象关联,是排好序的容器;大量随机访问使用ArrayList,经常从表中间插入或删除,使用LinkedList;各种Queue和栈的行为,由LinkedList提供支持;Map是将对象与对象相关联的设计。

yuexiaqiying的博客 747

Thinking in Java 第11章 持有对象(容器)

//声明:部分内容引自《Java编程思想(第四版)》机械工业出版社– 使用泛型容器:ArrayList<Apple> apples = new ArrayList<Apple>(); 可以在编译期防止将错误类型的对象放置到容器中;在取出元素时,也不必强制类型转换。– 所有的 Collection 都可以用 foreach 语法遍历。– 注意:package holding;//: holding/A

Tracy像太阳 474

Java编程思想--11持有对象--容器

第十一章 持有对象--容器11.1 泛型和类型安全容器11.2 基本概念11.3 添加一组元素11.4 容器的打印11.5 List11.6 迭代器11.6.1 基本操作11.6.2 优点11.6.3 ListIterator11.7 LinkedList11.7.1 获取元素11.7.2 删除表头元素11.7.3 添加元素11.8 Stack11.9 Set11.10 Map11.11 Queu...

nianmaodu的博客 247

《Java编程思想》笔记11.持有对象

我觉得本章名字改成容器似乎更好理解,持有对象让人感到一头雾水 我们需要在任意时刻和任意位置创建任意数量的对象,所以依靠创建命名的引用来持有对象已经满足不了需求。 Java可以用数组和其他容器类来(List、Set、Queue、Map)来解决这个问题,不同的容器类有各自的特性,满足不同的需求。 11.1 范型和类型安全的容器 Java SE5之前是没有范型的,一个容器内(以List为例)可以放置...

weixin_39872516的博客 246

【笔记】《Java编程思想(第四版)》第11章-持有对象

第11章 持有对象 如果一个程序只包含固定数量的且其生命期都是已知的对象,那么这时一个非常简单的程序。 List、Set、Queue和Map。这些对象类型也称为集合类。但由于Java的类库使用了Collection这个名字指代该类库的一个特殊自己,所以我使用了范围更广的术语**“容器”**称呼它们。 Set对于每个值只保存一个对象,Map是允许你将某些对象与其他一些对象关联起来的关联数组,Java...

ZeromaXHe的博客 278

《JAVA编程思想》阅读笔记 第11章 持有对象

ArrayList<>,尖括号当中可以写多个类型参数,表示可以让列表存放的对象类型 java 容器类类库分为两个概念:Collection 与 Map ,而且容器不能存放基本数据类型,要经过自动包装机制将基本类型转化为对应的包装类型来存放。 Collection 包括: List(必须按照插入顺序保存元素)、Set(不能有重复元素)、Queue(按排队规则确定对象产生顺序,通常与插...

搬砖咸鱼 222

《Thinkinginjava》第11章-持有对象

本章介绍了对象的持有技术,其实就是java中的容器,不作详细记录,只记录一些平时忽略掉的重点:java中其实只有四种容器:Map、List、Set和Queue。 Iterator只能前向移动,ListIterator只能用于各种List的访问,但是它能双向移动。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator,也可以通过listIterator(n)方

无不可编 616
上一篇: 第10章 内部类(java编程思想)
下一篇: 第二章 添加样式(精通CSS)
printf_myself
博客等级 码龄7年 1粉丝 19原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值