Class as a Generic in java - java

I know how to use generics in java but if an instance is given as
List<someclass> ai = new List<someclass>();
How can I use the list in this case? How can I access and modify elements in the class?
Please provide an example.

You can use it mostly like any non-generic list.
Here is an example with a list of Strings that shows inserting, getting and deleting elements as well as checking for their existence:
package example;
import java.util.ArrayList;
import java.util.List;
public class Example {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("foo");
list.add("bar");
// Get/extract the first element
// You can then call methods on
// that element, e.g. list.get(0).toUpperCase(...)
String firstElement = list.get(0);
System.out.println("First Element: " + firstElement);
// Remove the first element
list.remove("foo");
firstElement = list.get(0);
System.out.println("First Element after delete: " + firstElement);
// Check whether the list contains an object
if (list.contains("bar")) {
System.out.println("List contains bar.");
} else {
System.out.println("List doesn't contain bar.");
}
}
}
Outputs:
First Element: foo
First Element after delete: bar
List contains bar.
You can use generics in method parameters to only accept lists that contain certain types of elements:
package example;
import java.util.ArrayList;
import java.util.List;
public class Example {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("foo");
list.add("bar");
printAll(list);
}
public static void printAll(List<String> list) {
for (String str : list) {
System.out.println(str);
}
}
}
Outputs:
foo
bar
The following however is invalid, because you would try to insert an Integer into a Strings-only list:
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add(1);
}

The line of code you provided is not correct. List is an interface and interfaces cannot be instantiated. If you want to define a variable of type List<ClassName>, you have to initialize it with a constructor of a subclass. The most common subclass for the List<> interface is the ArrayList<> class. So your line of code should be:
List<SomeClass> ai = new ArrayList<SomeClass>();
Here you can find more information for interfaces.

Related

How to iterate arraylists within an arraylist, and insert their data onto an array

Let's say I have an array that takes instances of the type "Pessoal":
Pessoal[] teste = new Pessoal[6];
Now let's say I have 2 arraylists that are inside of an arraylist:
static ArrayList<Pessoal> lista_de_profs; // This one has 4
static ArrayList<Pessoal> lista_de_infos; // And this one has 2, matching the 6 on "teste"
// these arrayslists have instances of the type "Pessoal"
ArrayList<ArrayList<Pessoal>> lista_de_docentes = new ArrayList<>();
lista_de_docentes.add(lista_de_profs);
lista_de_docentes.add(lista_de_infos);
How do I iterate through the arraylist (lista_de_docentes) that contains more arraylists (lista_de_profs & lista_de_infos), and get their instances, so I can put them inside the array?
This works if teste's length is 4
for (int i = 0; i < teste.length; i++){
teste[i] = lista_de_profs.get(i);
}
But this only covers one arraylist, and I want all of the ones inside "lista_de_docentes", which are: "lista_de_profs" and "lista_de_infos"
*Some code in here, the language is in Portuguese, but I can change it to english, if it becomes confusing.
I hope I was clear, and thanks.
You can collect all your "Pessoal" elements into a single arraylist and then move the elements to your array
List<Pessoal> all= lista_de_docentes.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
for (int i =0; i < all.size(); i++)
teste[i] = all.get(i);
Or you can directly create the array (in case you don't care about the size)
Pessoal[] teste = lista_de_docentes.stream()
.flatMap(List::stream)
.collect(Collectors.toList())
.toArray(Pessoal[]::new);
You can do this with the stream API.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Pessoal {
public static void main(String[] args) {
ArrayList<Pessoal> lista_de_profs = new ArrayList<>();
ArrayList<Pessoal> lista_de_infos = new ArrayList<>();
ArrayList<ArrayList<Pessoal>> lista_de_docentes = new ArrayList<>();
lista_de_docentes.add(lista_de_profs);
lista_de_docentes.add(lista_de_infos);
Pessoal[] teste = lista_de_docentes.stream()
.flatMap(l -> l.stream())
.collect(Collectors.toList())
.toArray(new Pessoal[0]);
System.out.println(Arrays.toString(teste));
}
}
lista_de_docentes.stream() creates a stream where every element has type ArrayList<Pessoal>.
flatMap returns a stream where every element has type Pessoal.
All the stream [Pessoal] elements are collected and put into a List.
Method toArray (of interface List) converts the List to an array.
Alternatively, if you don't want to use streams:
import java.util.ArrayList;
import java.util.Arrays;
public class Pessoal {
public static void main(String[] args) {
ArrayList<Pessoal> lista_de_profs = new ArrayList<>();
ArrayList<Pessoal> lista_de_infos = new ArrayList<>();
ArrayList<ArrayList<Pessoal>> lista_de_docentes = new ArrayList<>();
lista_de_docentes.add(lista_de_profs);
lista_de_docentes.add(lista_de_infos);
ArrayList<Pessoal> temp = new ArrayList<>();
for (ArrayList<Pessoal> list : lista_de_docentes) {
for (Pessoal p : list) {
temp.add(p);
}
}
Pessoal[] teste = new Pessoal[temp.size()];
temp.toArray(teste);
System.out.println(Arrays.toString(teste));
}
}
By the way, you should consider adopting Java naming conventions.

Overloading same method to print different data type arraylist

My task is to overload the same method, to be able to use the same method name, to print to screen, the contents of the both array list contents.
Below is my code I have tried. But it's not working because both methods have same name?
import java.util.ArrayList;
public class Tutotrial_2_1 {
public static void main(String[] args){
//Creating integer type array list
ArrayList<Integer>listOfAges = new ArrayList<Integer>();
//Adding items to array list
listOfAges.add(25);
listOfAges.add(36);
listOfAges.add(45);
listOfAges.add(67);
listOfAges.add(87);
listOfAges.add(32);
listOfAges.add(33);
listOfAges.add(45);
//Creating double type array list
ArrayList<Double>listOfMarks = new ArrayList<Double>();
//Adding items to array list
listOfMarks.add(25.4);
listOfMarks.add(36.5);
listOfMarks.add(4.45);
listOfMarks.add(55.67);
listOfMarks.add(55.7);
listOfMarks.add(32.0);
listOfMarks.add(33.0);
listOfMarks.add(45.0);
//Calling display function of integer array
displayArray(listOfAges);
displayArray(listOfMarks);
}
//Display fucntion of listOfAges array
public static void displayArray(ArrayList<Integer>list){
for(Integer indexes : list){
System.out.println(indexes);
}
}
public static void displayArray(ArrayList<Double>list){
for(Double indexes : list){
System.out.println(indexes);
}
}
}
Due to Java's type erasure you can't overload a method over a generic type. In other words, you have two methods that resolve to displayArray(ArrayList), so you'll get a compilation error for a doubly declared method.
Luckily, you don't really need an overloaded method here - since any object in Java has a toString method, you can just have one method that receives a list, iterates over it, and print each item:
public static void displayArray(List<?> list){
for (Object indexes : list) {
System.out.println(indexes);
}
}
If I understand your problem if you change your method like this:
public static void main(String[] args) {
//Creating integer type array list
ArrayList<Integer> listOfAges = new ArrayList<Integer>();
//Adding items to array list
listOfAges.add(25);
listOfAges.add(36);
listOfAges.add(45);
listOfAges.add(67);
listOfAges.add(87);
listOfAges.add(32);
listOfAges.add(33);
listOfAges.add(45);
//Creating double type array list
ArrayList<Double>listOfMarks = new ArrayList<Double>();
//Adding items to array list
listOfMarks.add(25.4);
listOfMarks.add(36.5);
listOfMarks.add(4.45);
listOfMarks.add(55.67);
listOfMarks.add(55.7);
listOfMarks.add(32.0);
listOfMarks.add(33.0);
listOfMarks.add(45.0);
//Calling display function of integer array
displayArray(listOfAges);
displayArray(listOfMarks);
}
//Display function of listOfAges array
public static <T> void displayArray(ArrayList<T>list){
for(T indexes : list){
System.out.println(indexes);
}
}
It should work. The is use as a generic type.

Concurrent Modification Exception while adding elements to ArrayList recursively

Getting Concurrent Modification Exception while adding elements to ArrayList recursively.
import java.util.*;
public class Hello {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String str = sc.next();
System.out.println(gss(str));
}
public static ArrayList<String> gss(String str) {
if(str.length() == 0){
ArrayList<String> list = new ArrayList<String>();
list.add("");
return list;
}
ArrayList<String> list = gss(str.substring(1));
for(String temp : list){
list.add(str.charAt(0)+temp); // Problem
}
return list;
}
}
Solution: To just form new ArrayList at each call stack and return it.
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String str = sc.next();
System.out.println(gss(str));
}
public static ArrayList<String> gss(String str) {
if(str.length() == 0){
ArrayList<String> list = new ArrayList<String>();
list.add("");
return list;
}
ArrayList<String> list = gss(str.substring(1));
ArrayList<String> listToReturn = new ArrayList<>();
for(String temp : list){
listToReturn.add(temp);
}
for(String temp : list){
listToReturn.add(str.charAt(0) + temp);
}
return listToReturn;
}
}
I have recently come across this blog.
Which says, It uses a transient variable called modCount, which keeps track of how many times a list is modified structurally. Structural modifications are those that change the size of the list, which may affect the progress of iteration and may yield incorrect results. Both Iterator and ListIterator uses this field to detect unexpected change. Other methods of List which structurally modify List also uses this method e.g. add(), remove().
Cause: The real cause of ConcurrentModficationException is inconsistent modCount. When you are iterating over ArrayList then Iterator's next() method keep track of modCount. If you modify the collection by adding or removing element then modCount will change and it will not match with the expected modCount, hence Iterator will throw ConcurrentModificationException.

Type mismatch: convert from String to List<String>

I have in mind the algorithm of my school-class program, but also difficulty in some basics I guess...
here is my code with the problem:
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
String allWords = System.getProperty("user.home") + "/allwords.txt";
Anagrams an = new Anagrams(allWords);
for(List<String> wlist : an.getSortedByAnQty()) {
//[..............];
}
}
}
public class Anagrams {
List<String> myList = new ArrayList<String>();
public List<String> getSortedByAnQty() {
myList.add("aaa");
return myList;
}
}
I get "Type mismatch: cannot convert from element type String to List"
How should initialise getSortedByAnQty() right?
an.getSortedByAnQty() returns a List<String>. When you iterate over that List, you get the individual Strings, so the enhanced for loop should have a String variable :
for(String str : an.getSortedByAnQty()) {
//[..............];
}
If the main method should remain as is, you should change getSortedByAnQty to return a List<List<String>>.
char[] cArray = "MYString".toCharArray();
convert the string to an array as above and then iterate over the character array to form a list of String as below
List<String> list = new ArrayList<String>(cArray.length);
for(char c : cArray){
list.add(String.valueOf(c));
}

Why i am getting "Remove type arguments" error for "List<String> list1 = new ArrayList<String>();"

i am trying to implementing ArrayList using String array.
while implementing i am getting Remove type arguments error in my eclipse.
ArrayList.java
import java.util.List;
public class ArrayList {
public static void main(String [] a)
{
String [] things = {"eggs","chicken","milk","butter"};
List<String> list1 = new ArrayList<String>();
for(String s: things)
list1.add(s);
String [] morethings = {"chicken","milk"};
List<String> list2 = (List<String>) new ArrayList ();
for(String y: morethings)
list2.add(y);
for(int i=0; i<list1.size();i++)
{
System.out.printf("%s ", list1.get(i));
}
}
}
You've defined your own ArrayList which is not a generic class. To use java.util.ArrayList simply rename your class to something else other than one of Java's built-in classes
You have used the class java.awt.List which is used for GUI List options such as creating a drop-down list, and thus one cannot use collectibles/data structure, Iterators with such a list.
You need to use java.util.List for implementing:
List>= new LinkedList>();

Categories