So a part of my homework is to get a string of integer numbers and put each one of them in a list, this is what I have done:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String N;
int count;
LinkedList<Integer> booksList = new LinkedList<>();
System.out.printf("Give: ");
N = input.nextLine();
String[] arr = N.split(" ");
for (count = 0; count < arr.length - 2; count++) {
booksList.add(Integer.parseInt(arr[count + 2]));
}
So what I've done is take the string, split it into an array and then take the items with the for loop and put them into a list. What I am confused with is that I see people using the add command with a "new" inside the parentheses like this:
booksList.add(new Integer.parseInt(arr[count + 2]));
This is confusing me and I'm not totally sure if I'm doing this the right way.
By the way, I take the array elements from count + 2 because I do not need the first two elements of the answer but I need to store the first two integers in two separate variables.
Also I've seen some people write this:
List<Integer> booksList = new LinkedList<>();
Is there any difference from that and what I've written?
The construct
List<Integer> booksList = new LinkedList<>();
is often seen for mainly 2 reasons:
a) You aren't sure what the best collection for your purpose is. There are many candidates: Arrays, Sets, Lists, Vector, Map and so on, but you have to use something specific. So on the right hand side it has to be concrete, but on the left hand side, you try to be as wide open as possible.
Very often you just do iterate over the collection, use a for loop, search, sort, put into, take from, delete.
If you find out, that a sibling of your first thought is better suited, you can later change the RHS, without need to rewrite the rest of your program, because, for example, most methods of LinkedList and ArrayList fullfill the same contract, defined in List.
b) You get mor compatible to the outside world, if you use the wider object. Of course, you can't use something as vague as Object, since Object has no .add (E) Method.
But for sorting, searching and so on List is well suited. Have a look at the documentation, and compare List, LinkedList and ArrayList. Try to replace the one with another in your code.
Maybe two 'sublist (int fromIndex, int toIndex)' methods, in Linked~ and ArrayList are defined in the base class, and behave identically.
But maybe they are specialized, and implement subList on their own. Here we have a Interface <- Class relationship, so we know, that there is no implementation in the Interface, it is completly abstract. But in the case of (Abstract) base classes <- derived classes the pattern is the same.
Derived/implementing classes share the same interface, 'public List sublist (int fromIndex, int toIndex)'. You expect them to produce the same result, but in different ways - maybe.
Only if you need to call a method which is only present in, say LinkedList, you either declare your bookList as LinkedList up front, or you cast it for that purpose:
List<Integer> books = new LinkedList<>();
// ...
LinkedList <Integer> booksLiLi = (LinkedList <Integer>) books <> ();
// do something with booksLiLi which isn't defined on the List interface.
Sidenote: Your code can be simplified with the modern (7 years old) foreach-loop:
Scanner input = new Scanner (System.in);
LinkedList<Integer> booksList = new LinkedList<>();
System.out.printf ("Give: ");
String N = input.nextLine ();
String[] arr = answer.split (" ");
for (String num: arr) {
booksList.add (Integer.parseInt (num));
}
bookList.remove ();
bookList.remove ();
But if you declare a Scanner, you can take Integers from the Scanner directly:
Scanner input = new Scanner (System.in);
LinkedList<Integer> booksList = new LinkedList<>();
System.out.printf ("Give: ");
while (input.hasNextInt ()) {
booksList.add (input.nextInt ());
}
bookList.remove ();
bookList.remove ();
In reaction to the comments, here is a third code: Reading from System.in a line, and then creating a Scanner on that that line:
String line = input.nextLine ();
Scanner valueLine = new Scanner (line);
List<Integer> books = new LinkedList<>();
while (valueLine.hasNextInt ()) {
books.add (valueLine.nextInt ());
}
The function Integer.parseInt returns a new Integer so you do not need to use the new keyword.
Keep experimenting and use an IDE such as Eclipse that will highlight compile errors and you will learn the language soon enough. If you still are struggling read online tutorials or ask your professor.
Your code is fine.
The following:
booksList.add(new Integer.parseInt(arr[count + 2]));
is not syntactically correct, whereas what you have is.
As to List<Integer> booksList = ... vs LinkedList<Integer> booksList = ..., I consider the former to be slightly better style. However, it is sometimes necessary to use the latter. The difference is largely stylistic and I wouldn't worry about it too much right now.
Finally, I'd like to echo what others have said in the comments: declare variables when they're first used and not before. Also, don't reuse variables.
A List in Java is an interface, from which the methods are defined in specific implementations. For example, LinkedList implements the List interface, and creates its own version of add, delete and other methods. This is pretty important, since other data structures, such as ArrayList also implement the List interface. Add, delete, and other methods operate very differently in LinkedList and ArrayList.
When you write
List<Integer> booksList = new LinkedList<>()
it operates the same as
LinkedList<Integer> booksList = new LinkedList<>()
since the new keyword creates a LinkedList object which is bound to the name booksList. booksList just happens to be a List object in the first example, from which LinkedList implements.
Check the docs and see what data structures implement the List interface. You'll be surprised how many ways a List<Integer> newList = new .... is valid code.
One thing that hasn't been mentioned is its a good idea to pass on the generic type in all the angle brackets when declaring a data structure.
ie List<Integer> booksList = new LinkedList<Integer>()
Related
So I am trying to create an for loop to find unique elements in a ArrayList.
I already have a ArrayList stored with user input of 20 places (repeats are allowed) but I am stuck on how to count the number of different places inputted in the list excluding duplicates. (i would like to avoid using hash)
Input:
[park, park, sea, beach, town]
Output:
[Number of unique places = 4]
Heres a rough example of the code I'm trying to make:
public static void main(String[] args) {
ArrayList<City> place = new ArrayList();
Scanner sc = new Scanner(System.in);
for(...) { // this is just to receive 20 inputs from users using the scanner
...
}
# This is where i am lost on creating a for loop...
}
you can use a Set for that.
https://docs.oracle.com/javase/7/docs/api/java/util/Set.html
Store the list data to the Set.Set will not have duplicates in it, so the size of set will be the elements without duplicates.
use this method to get the set size.
https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#size()
Sample Code.
List<String> citiesWithDuplicates =
Arrays.asList(new String[] {"park", "park", "sea", "beach", "town"});
Set<String> cities = new HashSet<>(citiesWithDuplicates);
System.out.println("Number of unique places = " + cities.size());
If you are able to use Java 8, you can use the distinct method of Java streams:
int numOfUniquePlaces = list.stream().distinct().count();
Otherwise, using a set is the easiest solution. Since you don't want to use "hash", use a TreeSet (although HashSet is in most cases the better solution). If that is not an option either, you'll have to manually check for each element whether it's a duplicate or not.
One way that comes to mind (without using Set or hashvalues) is to make a second list.
ArrayList<City> places = new ArrayList<>();
//Fill array
ArrayList<String> uniquePlaces = new ArrayList<>();
for (City city : places){
if (!uniquePlaces.contains(city.getPlace())){
uniquePlaces.add(city.getPlace());
}
}
//number of unique places:
int uniqueCount = uniquePlaces.size();
Note that this is not super efficient =D
If you do not want to use implementations of Set or Map interfaces (that would solve you problem with one line of code) and you want to stuck with ArrayList, I suggest use something like Collections.sort() method. It will sort you elements. Then iterate through the sorted array and compare and count duplicates. This trick can make solving your iteration problem easier.
Anyway, I strongly recommend using one of the implementations of Set interface.
Use following answer. This will add last duplicate element in distinct list if there are multiple duplicate elements.
List<String> citiesWithDuplicates = Arrays.asList(new String[] {
"park", "park", "sea", "beach", "town", "park", "beach" });
List<String> distinctCities = new ArrayList<String>();
int currentIndex = 0;
for (String city : citiesWithDuplicates) {
int index = citiesWithDuplicates.lastIndexOf(city);
if (index == currentIndex) {
distinctCities.add(city);
}
currentIndex++;
}
System.out.println("[ Number of unique places = "
+ distinctCities.size() + "]");
Well if you do not want to use any HashSets or similar options, a quick and dirty nested for-loop like this for example does the trick (it is just slow as hell if you have a lot of items (20 would be just fine)):
int differentCount=0;
for(City city1 : place){
boolean same=false;
for(City city2 : place){
if(city1.equals(city2)){
same=true;
break;
}
}
if(!same)
differentCount++;
}
System.out.printf("Number of unique places = %d\n",differentCount);
Can someone show me how to remove an object from an array. But here's the catch (well for me), the array is something like this
member[0] = new Member("John Cena" , "p000001");
I want to be able to search a name, then when that is detected, to be able to remove. is it possible?
public static void remove(){
System.out.println("Name: ");
String removeName = input.next();
System.out.println("ID: ");
String removeID = input.next();
for(int i = 0; i < member.length; i++){
//not sure if this is the right direction
}
}
EDIT: Cannot use ArrayList or list because of requirements in an Assignment. Would have used it since it is easier but can't.
You can either use an ArrayList (or better yet, ArrayList<Member>), which you can populate with members, and then use the indexOf method to search through.
Alternatively, if you have to or would rather use arrays, create a loop like you have that iterates through each index of your members array. The only tricky part is removal requires that you remove it from the array, and then shift each index in front of it down so that the blank space is remove.
In other words, you need to delete index i and use a loop so that you move the member at i + 1 down to i, member i + 2 moves down to i + 1, and so on until you reach the end of the array.
With all that being said, I'd encourage use of the ArrayList. It does all of the operations I just described for you and makes matters a lot easier.
Arrays are fixed-size. This means that the best you can do for an object array is set the value to null. If you want to remove it completely, you'll want to use ArrayList instead. In that case,
ArrayList<Member> members = new ArrayList<Member>();
for (int i = members.length-1; i>=0; i--) {
if (members.get(i).getName().equals(toRemove)) {
members.remove(i);
}
}
Sorry for my previous wrong answer. This should be the correct way of removing your Members
List<Member> l = new ArrayList<>(Arrays.asList(member));
for (Iterator<Member> iter = l.listIterator(); iter.hasNext(); ) {
Member a = iter.next();
if ( (a.getId() == removeID) || (removeName.equals(a.getName)) ) {
iter.remove();
}
}
Member[] newMembers = l.toArray(new Member[l.size()]);
PS: Please get removeID like this;
int removeID = input.nextInt();
It's a bit wonky that you have to use an array, because:
You can't truly guarantee that there isn't going to be more than one person with the same name, since the array doesn't guarantee unique entries.
Arrays don't dynamically resize, leaving you to have to do that yourself.
It can still be done though. Here's an example using Java 8's Stream API.
Let's assume you're looking for a Member with the same name and ID. Then, you're going to want to filter out any elements that are not that entry, collect them to a List, and then turn that List into an array.
So the result would be:
member = Arrays.stream(member)
.filter(m -> removeName.equals(m.getName())
&& removeID.equals(m.getID()))
.collect(Collectors.toList())
.toArray(new Member[0]);
What it comes down to is I'm attempting to construct a List<T> from the java.util.List package based on an enumerator, but here's the catch- I don't want the first value to be in the list. The way that I've come up with doing this... Well... It can't be a good thing.
Here's the code I'm using:
Arrays.asList(Arrays.asList(MyEnum.values()).remove(0));
This effectively creates a List<> from my enum, and removes the first value, then tries to create another list with the created list.
This may actually be the correct way to do it, but just looking at it is screaming "Inefficient". I showed it to a few people on a forum that I'm a member of and they all said how ugly it was, and laughed; However not a single one of them could/would provide a better way to go about doing it.
I don't think that code is really ugly or inefficient. The bigger problem is it doesn't work because the list returned by Arrays.asList is backed by the underlying array, and so it has a fixed size.
You can use subList instead of remove to get it working:
List<MyEnum> list = Arrays.asList(MyEnum.values());
list = list.subList(1, list.size());
This means that the resulting list actually consists of two list objects (the asList and its subList), which may or may not bother you. However, you can create a flat ArrayList from the resulting list:
list = new ArrayList<>(list);
If you'd rather minimize object allocation, loop the values and add them to a single list directly:
MyEnum[] values = MyEnum.values();
List<MyEnum> list = new ArrayList<>(values.length - 1);
for (int i = 1; i < values.length; i++)
list.add(values[i]);
How about:
Arrays.asList(MyEnum.values()).subList(1, MyEnum.values().length);
Are you sure you can't (wouldn't want to) use MyEnum.values and treat your first element differently where it's used?
public enum Enums {
first,
b,
c,
d,
e,
f;
public boolean isFirst(Enums e) {
return e == first;
}
}
This would work:
List<T> enums = Arrays.asList(Arrays.copyOfRange(MyEnum.values(), 1, MyEnum.values().length - 1));
Or java 8:
Arrays.stream(MyEnum.values()).collect(Collectors.toList()).subList(1, MyEnum.values() - 1);
Hmmm... not much better .
I am writing a program that will take input of polynomials. Needing to create a new ArrayList for each polynomial input, I am needing a way to name each list without knowing the amount of polynomial beforehand. If a file has 2 polynomials I will need to name 2 arrays, but if more polynomials I will need to name more arrays. Is there anyway to automatically name arrays or variables with the iteration of a loop. I cannot figure out how. Variable names such as : P1 , P2, P3 etc. as the number of Polynomials increases is what I am searching for. Each polynomial will be read in line by line. I have attached my code, Though it is nowhere near complete. I imagine I will need to move the PolyCalc creation into the while loop and create a new PolyCalc for each line of input. I am looking to add this feature to the while loop in the main method.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class PolyProcessor {
static int polyNum = 0;
public static void main(String[] args) throws FileNotFoundException{
File polyfile = new File("polyinput.txt");
Scanner read = new Scanner(polyfile);
while (read.hasNextLine()){
PolyCalc c = new PolyCalc();
String j = read.nextLine();
c.add(j.split(";"));
polyNum++;}
}
}
class PolyCalc{
static int polyCount = 0;
static ArrayList polynomials = new ArrayList();
static void add(String[] strings){
for(int i = 0; i<strings.length;i++){
polynomials.add(strings[i]);
polyCount++;}
}
static Object get(int i){
return polynomials.get(i);
}
}
Why not use a (Hash) Map where the key is the variable name?
Map polys = new HashMap();
int count=0;
For ...
string key = String.format("p%02d",count++);
polys.put(key, newPoly(...));
I'd have to look up the String.format but something like that.
The order needs to be preserved so just choose long enough zero padded keys that you can sort. And/or use a linkedHashMap which keeps the insertion order.
As Stephen's answer and you said that arraylist is mandatory you could still use ArrayList
ArrayList numbers = new ArrayList();
HashMap<String,ArrayList> myPolys = new HashMap<String,ArrayList>();
and to use the HashMap
myPolys.put(what do you want to call them or your so "called" variables , numbers);
First of all, you can't do this using variables. Java does not allow you to declare variables dynamically. It is not that kind of programming language ...
If it is mandatory that the polynomials are stored in an ArrayList then:
get the user to refer to the polynomials by number (i.e. position in the list) instead of by name, or
create a hashmap that maps from names to positions in the list, or
store the polynomials in BOTH an ArrayList<String> AND a HashMap<String, String>.
Actually, I think that you may have misinterpreted the requirements for your programming exercise. I suspect that you are asked to represent each individual polynomial as an ArrayList (or a custom class that has an ArrayList inside it). Representing a polynomial as a String doesn't allow you to do any operations on it ... without first parsing the String and turning it into another form.
As you absolutely need to use ArrayList class to store your polynomials you can use its add(int index, E Element) method as follows:
List polynomials= new ArrayList();
for(int k=0;k < counter;k++){
polynomials.add(k, new Poly(...));
}
You won't have P0, P1, ... but polynomials.get(0), polynomials.get(1), ...
Thanks to gmhk in this.
I've done some searching but I wasn't able to find a valid solution. I have an arraylist storing Strings such as gum, socks, OJ, dog food...
I am having trouble iterating the list to determine the total number of differnt types of items.
ie.
ArrayList<String> Store = new ArrayList<String>();
this.Store.add("Gum");
this.Store.add("Gum");
this.Store.add("Socks");
this.Store.add("Candy");
The list has 4 total items, but only three different kinds of items (Gum, Sucks, Candy).
How would I design a method to calculate the 3?
What Bhesh Gurung said, but in code:
int numUnique = new HashSet<String>(Store).size();
If what you actually have is StoreItems and need to go through getName() then I would do
Set<String> itemNames = new HashSet<String>();
for (StoreItem item : Store)
itemNames.add(item.getName());
int numUnique = itemNames.size();
Use a Set (HashSet) whose size will give you what you are looking for.
This looks like a homework... So, if you do not understand the HashSet solution proposed above (or doning the same with a HashMap), think about doing something like this:
Create a new ArrayList
Take an element and check to see if it exists in the new ArrayList
If it is present in the new ArrayList, do nothing. Else add it.
Do this until you have examined the last element of the ArrayList.
Then, the size of the new array list should be the number you are looking for.
You can use the lastIndexOf method and loop through the arraylist.
char count=0;
for(char i=0; i<araylist.size(); i++){
if(i == araylist.lastIndexOf(araylist.get(i))){
count++;
}
}
Tested.